ntdsextract2 1.4.31

Display contents of Active Directory database files (ntds.dit)
use getset::Getters;
use libntdsextract2::{ntds::{EntryAttribute, NtdsAttributeId}, CDatabase};

use crate::walk::attribute_line::AttributeLine;

#[derive(Getters)]
#[getset(get = "pub")]
pub struct AttributeLineSet {
    lines: Vec<AttributeLine>,
}

impl AttributeLineSet {
    pub fn from(database: &CDatabase<'_, '_>, id: &NtdsAttributeId, attr: &EntryAttribute) -> Self {
        let name: &'static str = id.into();
        let values: Vec<_> = attr
            .original_record()
            .format_attribute(database, *id)
            .map_err(|why| {
                log::error!("Error while reading attribute {name}: {why}");
                Ok::<Option<Vec<String>>, ()>(None::<Vec<String>>)
            })
            .ok()
            .flatten()
            .unwrap_or_default();
        let has_siblings = values.len() > 1;
        let mut lines: Vec<_> = values
            .into_iter()
            .enumerate()
            .map(|(index, v)| AttributeLine::new(name.to_owned(), index, v, has_siblings))
            .collect();
        if lines.is_empty() {
            lines.push(AttributeLine::new(
                name.to_owned(),
                0,
                "".to_owned(),
                has_siblings,
            ));
        }
        Self { lines }
    }

    pub fn into_lines(self) -> Vec<AttributeLine> {
        self.lines
    }
}

#[derive(Eq, PartialEq, PartialOrd, Ord, Clone, Copy)]
pub struct AttributeSetId(usize);

impl From<usize> for AttributeSetId {
    fn from(value: usize) -> Self {
        Self(value)
    }
}