use enumflags2::{BitFlag, FromBitsError};
use lalrpop_util::ParseError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("ParseError: {0}")]
ParseError(String),
#[error("IllegalSid: '{0}' (reason: {1})")]
IllegalSidFormat(String, &'static str),
#[error("this SID alias cannot be parsed without a domain RID")]
MissingDomainInformation,
#[error("illegal SID alias: {0}")]
IllegalSidAlias(String),
#[error("Error while parsing the binary security descriptor: {0}")]
BinReadError(#[from] binrw::Error),
#[error("This flag field has invalid bits set: {0}")]
InvalidFlags(String),
#[error("This is not a known alias")]
IllegalAlias(#[from] strum::ParseError),
}
impl<L, T, E> From<ParseError<L, T, E>> for Error
where
L: core::fmt::Display,
T: core::fmt::Display,
E: core::fmt::Display,
{
fn from(value: ParseError<L, T, E>) -> Self {
Self::ParseError(format!("{value}"))
}
}
impl From<&str> for Error {
fn from(value: &str) -> Self {
Self::ParseError(value.into())
}
}
impl<T> From<FromBitsError<T>> for Error
where
T: BitFlag,
{
fn from(value: FromBitsError<T>) -> Self {
let bits = value.invalid_bits();
Self::InvalidFlags(format!("{bits:?}"))
}
}
impl From<dfir_windows_types::Error> for Error {
fn from(value: dfir_windows_types::Error) -> Self {
match value {
dfir_windows_types::Error::ConversionError(_) => panic!("unsupported error type"),
dfir_windows_types::Error::IllegalSidFormat(a, b) => Self::IllegalSidFormat(a, b),
dfir_windows_types::Error::MissingDomainInformation => Self::MissingDomainInformation,
dfir_windows_types::Error::BinaryParserError(why) => Self::ParseError(why),
}
}
}