use core::fmt;
use core::fmt::Display;
#[cfg(feature = "std")]
use std::error;
use crate::phys::{BinaryDecodeError, BinaryDecoder, BinaryEncodeError, BinaryEncoder};
#[derive(Debug)]
pub struct AcePermission {
pub value: u32,
}
impl Display for AcePermission {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut count = 0;
for (mask, string) in &AcePermission::STRINGS {
if (mask & self.value) == *mask {
let sep = match count {
0 => "",
_ => "|",
};
write!(f, "{sep}{string}")?;
count += 1;
}
}
let unknown = self.value - (self.value & AcePermission::MASK);
if unknown != 0 {
let sep = match count {
0 => "",
_ => "|",
};
write!(f, "{sep}{unknown:#08x}")?;
}
Ok(())
}
}
impl AcePermission {
pub const READ_DATA: u32 = 0x00000001;
pub const LIST_DIRECTORY: u32 = 0x00000001;
pub const WRITE_DATA: u32 = 0x00000002;
pub const ADD_FILE: u32 = 0x00000002;
pub const APPEND_DATA: u32 = 0x00000004;
pub const ADD_SUBDIRECTORY: u32 = 0x00000004;
pub const READ_NAMED_ATTRIBUTES: u32 = 0x00000008;
pub const WRITE_NAMED_ATTRIBUTES: u32 = 0x00000010;
pub const EXECUTE: u32 = 0x00000020;
pub const TRAVERSE: u32 = 0x00000020;
pub const DELETE_CHILD: u32 = 0x00000040;
pub const READ_ATTRIBUTES: u32 = 0x00000080;
pub const WRITE_ATTRIBUTES: u32 = 0x00000100;
pub const DELETE: u32 = 0x00010000;
pub const READ_ACL: u32 = 0x00020000;
pub const WRITE_ACL: u32 = 0x00040000;
pub const WRITE_OWNER: u32 = 0x00080000;
pub const SYNCHRONIZE: u32 = 0x00100000;
pub const MASK: u32 = (AcePermission::READ_DATA
| AcePermission::LIST_DIRECTORY
| AcePermission::WRITE_DATA
| AcePermission::ADD_FILE
| AcePermission::APPEND_DATA
| AcePermission::ADD_SUBDIRECTORY
| AcePermission::READ_NAMED_ATTRIBUTES
| AcePermission::WRITE_NAMED_ATTRIBUTES
| AcePermission::EXECUTE
| AcePermission::TRAVERSE
| AcePermission::DELETE_CHILD
| AcePermission::READ_ATTRIBUTES
| AcePermission::WRITE_ATTRIBUTES
| AcePermission::DELETE
| AcePermission::READ_ACL
| AcePermission::WRITE_ACL
| AcePermission::WRITE_OWNER
| AcePermission::SYNCHRONIZE);
const STRINGS: [(u32, &'static str); 18] = [
(AcePermission::READ_DATA, "READ_DATA"),
(AcePermission::LIST_DIRECTORY, "LIST_DIRECTORY"),
(AcePermission::WRITE_DATA, "WRITE_DATA"),
(AcePermission::ADD_FILE, "ADD_FILE"),
(AcePermission::APPEND_DATA, "APPEND_DATA"),
(AcePermission::ADD_SUBDIRECTORY, "ADD_SUBDIRECTORY"),
(
AcePermission::READ_NAMED_ATTRIBUTES,
"READ_NAMED_ATTRIBUTES",
),
(
AcePermission::WRITE_NAMED_ATTRIBUTES,
"WRITE_NAMED_ATTRIBUTES",
),
(AcePermission::EXECUTE, "EXECUTE"),
(AcePermission::TRAVERSE, "TRAVERSE"),
(AcePermission::DELETE_CHILD, "DELETE_CHILD"),
(AcePermission::READ_ATTRIBUTES, "READ_ATTRIBUTES"),
(AcePermission::WRITE_ATTRIBUTES, "WRITE_ATTRIBUTES"),
(AcePermission::DELETE, "DELETE"),
(AcePermission::READ_ACL, "READ_ACL"),
(AcePermission::WRITE_ACL, "WRITE_ACL"),
(AcePermission::WRITE_OWNER, "WRITE_OWNER"),
(AcePermission::SYNCHRONIZE, "SYNCHRONIZE"),
];
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(u8)]
pub enum AceType {
Allow = 0,
Deny = 1,
Audit = 2,
Alarm = 3,
AccessAllowCompound = 4,
AccessAllowObject = 5,
AccessDenyObject = 6,
SystemAuditObject = 7,
SystemAlarmObject = 8,
AccessAllowCallback = 9,
AccessDenyCallback = 10,
AccessAllowCallbackObject = 11,
AccessDenyCallbackObject = 12,
SystemAuditCallback = 13,
SystemAlarmCallback = 14,
SystemAuditCallbackObject = 15,
SystemAlarmCallbackObject = 16,
}
impl Display for AceType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AceType::Allow => write!(f, "Allow"),
AceType::Deny => write!(f, "Deny"),
AceType::Audit => write!(f, "Audit"),
AceType::Alarm => write!(f, "Alarm"),
AceType::AccessAllowCompound => write!(f, "AccessAllowCompound"),
AceType::AccessAllowObject => write!(f, "AccessAllowObject"),
AceType::AccessDenyObject => write!(f, "AccessDenyObject"),
AceType::SystemAuditObject => write!(f, "SystemAuditObject"),
AceType::SystemAlarmObject => write!(f, "SystemAlarmObject"),
AceType::AccessAllowCallback => write!(f, "AccessAllowCallback"),
AceType::AccessDenyCallback => write!(f, "AccessDenyCallback"),
AceType::AccessAllowCallbackObject => write!(f, "AccessAllowCallbackObject"),
AceType::AccessDenyCallbackObject => write!(f, "AccessDenyCallbackObject"),
AceType::SystemAuditCallback => write!(f, "SystemAuditCallback"),
AceType::SystemAlarmCallback => write!(f, "SystemAlarmCallback"),
AceType::SystemAuditCallbackObject => write!(f, "SystemAuditCallbackObject"),
AceType::SystemAlarmCallbackObject => write!(f, "SystemAlarmCallbackObject"),
}
}
}
impl From<AceType> for u16 {
fn from(val: AceType) -> u16 {
val as u16
}
}
impl TryFrom<u16> for AceType {
type Error = AceTypeError;
fn try_from(ace_type: u16) -> Result<Self, Self::Error> {
match ace_type {
0 => Ok(AceType::Allow),
1 => Ok(AceType::Deny),
2 => Ok(AceType::Audit),
3 => Ok(AceType::Alarm),
4 => Ok(AceType::AccessAllowCompound),
5 => Ok(AceType::AccessAllowObject),
6 => Ok(AceType::AccessDenyObject),
7 => Ok(AceType::SystemAuditObject),
8 => Ok(AceType::SystemAlarmObject),
9 => Ok(AceType::AccessAllowCallback),
10 => Ok(AceType::AccessDenyCallback),
11 => Ok(AceType::AccessAllowCallbackObject),
12 => Ok(AceType::AccessDenyCallbackObject),
13 => Ok(AceType::SystemAuditCallback),
14 => Ok(AceType::SystemAlarmCallback),
15 => Ok(AceType::SystemAuditCallbackObject),
16 => Ok(AceType::SystemAlarmCallbackObject),
_ => Err(AceTypeError::Unknown { ace_type }),
}
}
}
#[derive(Debug)]
pub enum AceTypeError {
Unknown {
ace_type: u16,
},
}
impl fmt::Display for AceTypeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AceTypeError::Unknown { ace_type } => {
write!(f, "Unknown AceType {ace_type}")
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for AceTypeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
None
}
}
#[derive(Debug)]
pub struct AceFlag {
pub value: u16,
}
impl Display for AceFlag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut count = 0;
for (mask, string) in &AceFlag::STRINGS {
if (mask & self.value) == *mask {
let sep = match count {
0 => "",
_ => "|",
};
write!(f, "{sep}{string}")?;
count += 1;
}
}
let unknown = self.value - (self.value & AceFlag::MASK);
if unknown != 0 {
let sep = match count {
0 => "",
_ => "|",
};
write!(f, "{sep}{unknown:#04x}")?;
}
Ok(())
}
}
impl AceFlag {
pub const FILE_INHERIT_ACE: u16 = 0x0001;
pub const DIRECTORY_INHERIT_ACE: u16 = 0x0002;
pub const NO_PROPAGATE_INHERIT_ACE: u16 = 0x0004;
pub const INHERIT_ONLY_ACE: u16 = 0x0008;
pub const SUCCESSFUL_ACCESS_ACE: u16 = 0x0010;
pub const FAILED_ACCESS_ACE: u16 = 0x0020;
pub const IDENTIFIER_GROUP: u16 = 0x0040;
pub const INHERITED_ACE: u16 = 0x0080;
pub const OWNER: u16 = 0x1000;
pub const GROUP: u16 = 0x2000;
pub const EVERYONE: u16 = 0x4000;
pub const TYPE: u16 =
(AceFlag::OWNER | AceFlag::GROUP | AceFlag::EVERYONE | AceFlag::IDENTIFIER_GROUP);
pub const OWNING_GROUP: u16 = AceFlag::GROUP | AceFlag::IDENTIFIER_GROUP;
pub const MASK: u16 = (AceFlag::FILE_INHERIT_ACE
| AceFlag::DIRECTORY_INHERIT_ACE
| AceFlag::NO_PROPAGATE_INHERIT_ACE
| AceFlag::INHERIT_ONLY_ACE
| AceFlag::SUCCESSFUL_ACCESS_ACE
| AceFlag::FAILED_ACCESS_ACE
| AceFlag::IDENTIFIER_GROUP
| AceFlag::INHERITED_ACE
| AceFlag::OWNER
| AceFlag::GROUP
| AceFlag::EVERYONE);
const STRINGS: [(u16, &'static str); 11] = [
(AceFlag::FILE_INHERIT_ACE, "FILE_INHERIT_ACE"),
(AceFlag::DIRECTORY_INHERIT_ACE, "DIRECTORY_INHERIT_ACE"),
(
AceFlag::NO_PROPAGATE_INHERIT_ACE,
"NO_PROPAGATE_INHERIT_ACE",
),
(AceFlag::INHERIT_ONLY_ACE, "INHERIT_ONLY_ACE"),
(AceFlag::SUCCESSFUL_ACCESS_ACE, "SUCCESSFUL_ACCESS_ACE"),
(AceFlag::FAILED_ACCESS_ACE, "FAILED_ACCESS_ACE"),
(AceFlag::IDENTIFIER_GROUP, "IDENTIFIER_GROUP"),
(AceFlag::INHERITED_ACE, "INHERITED_ACE"),
(AceFlag::OWNER, "OWNER"),
(AceFlag::GROUP, "GROUP"),
(AceFlag::EVERYONE, "EVERYONE"),
];
}
#[derive(Debug)]
pub struct AceV0 {
pub id: u32,
pub permissions: u32,
pub flags: u16,
pub ace_type: AceType,
}
impl AceV0 {
pub const SIZE: usize = 12;
pub fn from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<AceV0, AceDecodeError> {
let id = decoder.get_u32()?;
let permissions = decoder.get_u32()?;
let flags = decoder.get_u16()?;
let ace_type = AceType::try_from(decoder.get_u16()?)?;
if (permissions & AcePermission::MASK) != permissions {
return Err(AceDecodeError::Permissions { permissions });
}
if (flags & AceFlag::MASK) != flags {
return Err(AceDecodeError::Flags { flags });
}
match ace_type {
AceType::Allow | AceType::Deny | AceType::Audit | AceType::Alarm => (),
_ => return Err(AceDecodeError::UnexpectedType { ace_type }),
};
Ok(AceV0 {
id,
permissions,
flags,
ace_type,
})
}
pub fn to_encoder(&self, encoder: &mut dyn BinaryEncoder<'_>) -> Result<(), AceEncodeError> {
if (self.permissions & AcePermission::MASK) != self.permissions {
return Err(AceEncodeError::Permissions {
permissions: self.permissions,
});
}
if (self.flags & AceFlag::MASK) != self.flags {
return Err(AceEncodeError::Flags { flags: self.flags });
}
match self.ace_type {
AceType::Allow | AceType::Deny | AceType::Audit | AceType::Alarm => (),
_ => {
return Err(AceEncodeError::UnexpectedType {
ace_type: self.ace_type,
})
}
};
encoder.put_u32(self.id)?;
encoder.put_u32(self.permissions)?;
encoder.put_u16(self.flags)?;
encoder.put_u16(u16::from(self.ace_type))?;
Ok(())
}
}
#[derive(Debug)]
pub struct AclV0 {
pub object_id: Option<u64>,
pub count: u32,
pub aces: [AceV0; 6],
}
impl AclV0 {
pub const SIZE: usize = 88;
pub const VERSION: u16 = 0;
const PADDING_SIZE: usize = 2;
pub fn from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<AclV0, AclDecodeError> {
let object_id = match decoder.get_u64()? {
0 => None,
v => Some(v),
};
let count = decoder.get_u32()?;
let version = decoder.get_u16()?;
decoder.skip_zeros(AclV0::PADDING_SIZE)?;
if version != AclV0::VERSION {
return Err(AclDecodeError::Version { version });
}
Ok(AclV0 {
object_id,
count,
aces: [
AceV0::from_decoder(decoder)?,
AceV0::from_decoder(decoder)?,
AceV0::from_decoder(decoder)?,
AceV0::from_decoder(decoder)?,
AceV0::from_decoder(decoder)?,
AceV0::from_decoder(decoder)?,
],
})
}
pub fn to_encoder(&self, encoder: &mut dyn BinaryEncoder<'_>) -> Result<(), AclEncodeError> {
encoder.put_u64(self.object_id.unwrap_or(0))?;
encoder.put_u32(self.count)?;
encoder.put_u16(AclV0::VERSION)?;
encoder.put_zeros(AclV0::PADDING_SIZE)?;
for ace in &self.aces {
ace.to_encoder(encoder)?;
}
Ok(())
}
}
#[derive(Debug)]
pub struct AceV1Header {
pub ace_type: AceType,
pub flags: u16,
pub permissions: u32,
}
impl AceV1Header {
pub const SIZE: usize = 8;
pub fn from_decoder(
decoder: &mut dyn BinaryDecoder<'_>,
) -> Result<AceV1Header, AceDecodeError> {
let ace_type = AceType::try_from(decoder.get_u16()?)?;
let flags = decoder.get_u16()?;
let permissions = decoder.get_u32()?;
if (permissions & AcePermission::MASK) != permissions {
return Err(AceDecodeError::Permissions { permissions });
}
if (flags & AceFlag::MASK) != flags {
return Err(AceDecodeError::Flags { flags });
}
Ok(AceV1Header {
ace_type,
flags,
permissions,
})
}
pub fn to_encoder(&self, encoder: &mut dyn BinaryEncoder<'_>) -> Result<(), AceEncodeError> {
if (self.permissions & AcePermission::MASK) != self.permissions {
return Err(AceEncodeError::Permissions {
permissions: self.permissions,
});
}
if (self.flags & AceFlag::MASK) != self.flags {
return Err(AceEncodeError::Flags { flags: self.flags });
}
match self.ace_type {
AceType::Allow | AceType::Deny | AceType::Audit | AceType::Alarm => (),
_ => {
return Err(AceEncodeError::UnexpectedType {
ace_type: self.ace_type,
})
}
};
encoder.put_u16(u16::from(self.ace_type))?;
encoder.put_u16(self.flags)?;
encoder.put_u32(self.permissions)?;
Ok(())
}
}
#[derive(Debug)]
pub struct AceV1Simple {
pub header: AceV1Header,
}
#[derive(Debug)]
pub struct AceV1Id {
pub header: AceV1Header,
pub id: u64,
}
#[derive(Debug)]
pub struct AceV1Object {
pub header: AceV1Header,
pub object_guid: [u8; 16],
pub inherit_guid: [u8; 16],
}
#[derive(Debug)]
pub enum AceV1 {
Simple(AceV1Simple),
Id(AceV1Id),
Object(AceV1Object),
}
pub struct AceV1Iterator<'a, 'b> {
decoder: &'b mut dyn BinaryDecoder<'a>,
}
impl AceV1Iterator<'_, '_> {
pub fn from_decoder<'a, 'b>(
decoder: &'b mut dyn BinaryDecoder<'a>,
) -> Result<AceV1Iterator<'a, 'b>, AceDecodeError> {
Ok(AceV1Iterator { decoder })
}
}
impl<'a, 'b> Iterator for AceV1Iterator<'a, 'b> {
type Item = Result<AceV1, AceDecodeError>;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
if !self.decoder.is_empty() {
let header = match AceV1Header::from_decoder(self.decoder) {
Ok(v) => v,
Err(e) => return Some(Err(e)),
};
match header.ace_type {
AceType::AccessAllowObject
| AceType::AccessDenyObject
| AceType::SystemAuditObject
| AceType::SystemAlarmObject => {
let object_guid = match self.decoder.get_bytes_n(16) {
Ok(v) => v.try_into().unwrap(),
Err(e) => return Some(Err(AceDecodeError::Binary { err: e })),
};
let inherit_guid = match self.decoder.get_bytes_n(16) {
Ok(v) => v.try_into().unwrap(),
Err(e) => return Some(Err(AceDecodeError::Binary { err: e })),
};
let ace_object = AceV1Object {
header,
object_guid,
inherit_guid,
};
return Some(Ok(AceV1::Object(ace_object)));
}
AceType::Allow | AceType::Deny => match header.flags & AceFlag::TYPE {
AceFlag::OWNER | AceFlag::OWNING_GROUP | AceFlag::EVERYONE => {
let ace_simple = AceV1Simple { header };
return Some(Ok(AceV1::Simple(ace_simple)));
}
_ => (),
},
_ => (),
}
let id = match self.decoder.get_u64() {
Ok(v) => v,
Err(e) => return Some(Err(AceDecodeError::Binary { err: e })),
};
let ace_id = AceV1Id { header, id };
return Some(Ok(AceV1::Id(ace_id)));
}
None
}
}
#[derive(Debug)]
pub struct AclV1 {
pub object_id: Option<u64>,
pub size: u32,
pub count: u16,
pub aces: [u8; AceV0::SIZE * 6],
}
impl AclV1 {
pub const SIZE: usize = 88;
pub const VERSION: u16 = 1;
pub fn from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<AclV1, AclDecodeError> {
let object_id = match decoder.get_u64()? {
0 => None,
v => Some(v),
};
let size = decoder.get_u32()?;
let version = decoder.get_u16()?;
let count = decoder.get_u16()?;
if version != AclV1::VERSION {
return Err(AclDecodeError::Version { version });
}
let aces = decoder.get_bytes_n(AceV0::SIZE * 6)?;
Ok(AclV1 {
object_id,
size,
count,
aces: aces.try_into().unwrap(),
})
}
pub fn to_encoder(&self, encoder: &mut dyn BinaryEncoder<'_>) -> Result<(), AclEncodeError> {
encoder.put_u64(self.object_id.unwrap_or(0))?;
encoder.put_u32(self.size)?;
encoder.put_u16(AclV1::VERSION)?;
encoder.put_u16(self.count)?;
encoder.put_bytes(&self.aces)?;
Ok(())
}
}
#[derive(Debug)]
pub enum Acl {
V0(AclV0),
V1(AclV1),
}
impl Acl {
pub fn from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Acl, AclDecodeError> {
let offset = decoder.offset();
decoder.skip(12)?;
let version = decoder.get_u16()?;
decoder.seek(offset)?;
match version {
AclV0::VERSION => Ok(Acl::V0(AclV0::from_decoder(decoder)?)),
AclV1::VERSION => Ok(Acl::V1(AclV1::from_decoder(decoder)?)),
_ => Err(AclDecodeError::Version { version }),
}
}
pub fn to_encoder(&self, encoder: &mut dyn BinaryEncoder<'_>) -> Result<(), AclEncodeError> {
match self {
Acl::V0(acl) => acl.to_encoder(encoder),
Acl::V1(acl) => acl.to_encoder(encoder),
}
}
}
#[derive(Debug)]
pub enum AceDecodeError {
Binary {
err: BinaryDecodeError,
},
Permissions {
permissions: u32,
},
Flags {
flags: u16,
},
Type {
err: AceTypeError,
},
UnexpectedType {
ace_type: AceType,
},
}
impl From<BinaryDecodeError> for AceDecodeError {
fn from(err: BinaryDecodeError) -> Self {
AceDecodeError::Binary { err }
}
}
impl From<AceTypeError> for AceDecodeError {
fn from(err: AceTypeError) -> Self {
AceDecodeError::Type { err }
}
}
impl fmt::Display for AceDecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AceDecodeError::Binary { err } => {
write!(f, "Ace decode error | {err}")
}
AceDecodeError::Flags { flags } => {
write!(f, "Ace decode error, unknown flags {flags}")
}
AceDecodeError::Permissions { permissions } => {
write!(f, "Ace decode error, unknown permissions {permissions}")
}
AceDecodeError::Type { err } => {
write!(f, "Ace decode error | {err}")
}
AceDecodeError::UnexpectedType { ace_type } => {
write!(f, "Ace decode error, unexpected AceType {ace_type}")
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for AceDecodeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
AceDecodeError::Binary { err } => Some(err),
AceDecodeError::Type { err } => Some(err),
_ => None,
}
}
}
#[derive(Debug)]
pub enum AceEncodeError {
Binary {
err: BinaryEncodeError,
},
Flags {
flags: u16,
},
Permissions {
permissions: u32,
},
UnexpectedType {
ace_type: AceType,
},
}
impl From<BinaryEncodeError> for AceEncodeError {
fn from(err: BinaryEncodeError) -> Self {
AceEncodeError::Binary { err }
}
}
impl fmt::Display for AceEncodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AceEncodeError::Binary { err } => {
write!(f, "Ace encode error | {err}")
}
AceEncodeError::Flags { flags } => {
write!(f, "Ace encode error, unknown flags {flags}")
}
AceEncodeError::Permissions { permissions } => {
write!(f, "Ace encode error, unknown permissions {permissions}")
}
AceEncodeError::UnexpectedType { ace_type } => {
write!(f, "Ace encode error, unexpected AceType {ace_type}")
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for AceEncodeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
AceEncodeError::Binary { err } => Some(err),
_ => None,
}
}
}
#[derive(Debug)]
pub enum AclDecodeError {
Ace {
err: AceDecodeError,
},
Binary {
err: BinaryDecodeError,
},
Version {
version: u16,
},
}
impl From<AceDecodeError> for AclDecodeError {
fn from(err: AceDecodeError) -> Self {
AclDecodeError::Ace { err }
}
}
impl From<BinaryDecodeError> for AclDecodeError {
fn from(err: BinaryDecodeError) -> Self {
AclDecodeError::Binary { err }
}
}
impl fmt::Display for AclDecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AclDecodeError::Ace { err } => {
write!(f, "Acl decode error | {err}")
}
AclDecodeError::Binary { err } => {
write!(f, "Acl decode error | {err}")
}
AclDecodeError::Version { version } => {
write!(f, "Acl decode error, unknown version {version}")
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for AclDecodeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
AclDecodeError::Ace { err } => Some(err),
AclDecodeError::Binary { err } => Some(err),
_ => None,
}
}
}
#[derive(Debug)]
pub enum AclEncodeError {
Ace {
err: AceEncodeError,
},
Binary {
err: BinaryEncodeError,
},
}
impl From<AceEncodeError> for AclEncodeError {
fn from(err: AceEncodeError) -> Self {
AclEncodeError::Ace { err }
}
}
impl From<BinaryEncodeError> for AclEncodeError {
fn from(err: BinaryEncodeError) -> Self {
AclEncodeError::Binary { err }
}
}
impl fmt::Display for AclEncodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AclEncodeError::Ace { err } => {
write!(f, "Acl encode error | {err}")
}
AclEncodeError::Binary { err } => {
write!(f, "Acl encode error | {err}")
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for AclEncodeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
AclEncodeError::Ace { err } => Some(err),
AclEncodeError::Binary { err } => Some(err),
}
}
}