selinux/new_policy/
traits.rs1use std::fmt::Debug;
6use std::hash::Hash;
7
8use super::NewPolicy;
9use super::error::{ParseError, SerializeError, ValidateError};
10use super::parser::{PolicyCursor, PolicyWriter};
11
12pub trait Parse: Sized {
14 fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError>;
15}
16
17pub trait Serialize {
19 fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError>;
20}
21
22pub trait Validate {
24 fn validate(&self, policy: &NewPolicy) -> Result<(), ValidateError>;
25}
26
27pub trait PolicyId: Copy + Clone + Debug + Eq + Hash + PartialEq {
33 fn as_u32(&self) -> u32;
35
36 fn from_u32(value: u32) -> Option<Self>;
39}
40
41impl<T: PolicyId> Parse for T {
43 fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
44 let value = u32::parse(cursor)?;
45 T::from_u32(value).ok_or(ParseError::InvalidId { value })
46 }
47}
48
49impl<T: PolicyId> Serialize for T {
50 fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
51 self.as_u32().serialize(writer)
52 }
53}
54
55impl<T: PolicyId> Parse for Option<T> {
56 fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
57 let value = u32::parse(cursor)?;
58 if value == 0 {
59 Ok(None)
60 } else {
61 T::from_u32(value).map(Some).ok_or(ParseError::InvalidId { value })
62 }
63 }
64}
65
66impl<T: PolicyId> Serialize for Option<T> {
67 fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
68 match self {
69 Some(id) => id.as_u32().serialize(writer),
70 None => 0u32.serialize(writer),
71 }
72 }
73}
74
75pub trait HasName {
77 fn name(&self) -> &[u8];
78}
79
80pub trait HasPolicyId {
82 type Id: PolicyId;
83 fn id(&self) -> Self::Id;
84}
85
86impl<T: Validate> Validate for Box<T> {
87 fn validate(&self, policy: &NewPolicy) -> Result<(), ValidateError> {
88 (**self).validate(policy)
89 }
90}
91
92impl Validate for bool {
93 fn validate(&self, _policy: &NewPolicy) -> Result<(), ValidateError> {
94 Ok(())
95 }
96}
97
98impl<T: Validate> Validate for Option<T> {
99 fn validate(&self, policy: &NewPolicy) -> Result<(), ValidateError> {
100 if let Some(value) = self {
101 value.validate(policy)?;
102 }
103 Ok(())
104 }
105}