Skip to main content

selinux/new_policy/
traits.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use super::NewPolicy;
6use super::error::{ParseError, SerializeError, ValidateError};
7use super::parser::PolicyCursor;
8
9/// Trait for types that can be parsed from a [`PolicyCursor`].
10pub trait Parse: Sized {
11    fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError>;
12}
13
14/// Trait for types that can be serialized into a byte vector.
15pub trait Serialize {
16    fn serialize(&self, writer: &mut Vec<u8>) -> Result<(), SerializeError>;
17}
18
19/// Trait for types that can be validated against the parsed policy.
20pub trait Validate {
21    fn validate(&self, policy: &NewPolicy) -> Result<(), ValidateError>;
22}
23
24/// Trait for strongly-typed policy identifiers.
25///
26/// Types implementing [`PolicyId`] can be parsed from and serialized to `u32` values
27/// in the binary policy database, but are represented as strongly-typed integers
28/// (often wrapping `NonZeroU16` or `NonZeroU32`) in the logical domain model.
29pub trait PolicyId:
30    Copy + Clone + std::fmt::Debug + Eq + std::hash::Hash + Ord + PartialOrd
31{
32    /// Returns the raw `u32` value of the ID.
33    fn as_u32(&self) -> u32;
34
35    /// Constructs an instance of [`Self`] from a raw `u32` value, returning [`None`]
36    /// if the value is invalid (e.g. zero for a non-optional ID, or out of range).
37    fn from_u32(value: u32) -> Option<Self>;
38}
39
40// Blanket implementations for all strongly-typed IDs
41impl<T> Parse for T
42where
43    T: PolicyId,
44{
45    fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
46        let value = u32::parse(cursor)?;
47        T::from_u32(value).ok_or(ParseError::InvalidId { value })
48    }
49}
50
51impl<T> Serialize for T
52where
53    T: PolicyId,
54{
55    fn serialize(&self, writer: &mut Vec<u8>) -> Result<(), SerializeError> {
56        self.as_u32().serialize(writer)
57    }
58}
59
60impl<T> Validate for T
61where
62    T: PolicyId,
63{
64    fn validate(&self, _policy: &NewPolicy) -> Result<(), ValidateError> {
65        Ok(())
66    }
67}
68
69/// Trait for policy elements with a byte slice name.
70pub trait HasName {
71    fn name(&self) -> &[u8];
72}
73
74/// Trait for policy elements that have a strongly-typed policy identifier.
75pub trait HasPolicyId {
76    type Id: PolicyId;
77    fn id(&self) -> Self::Id;
78}
79
80impl Validate for Box<[u8]> {
81    fn validate(&self, _policy: &NewPolicy) -> Result<(), ValidateError> {
82        Ok(())
83    }
84}