mdict-rs 0.1.4

Library-first Rust parser for MDict .mdx and .mdd dictionaries
Documentation
use std::collections::BTreeMap;

/// Distinguishes text dictionaries (`.mdx`) from resource dictionaries
/// (`.mdd`).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ContainerKind {
    Mdx,
    Mdd,
}

/// Zero-based key ordinal within a specific dictionary file snapshot.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct KeyOrdinal(u64);

impl KeyOrdinal {
    /// Creates a zero-based key ordinal.
    pub const fn new(value: u64) -> Self {
        Self(value)
    }

    /// Returns the underlying zero-based ordinal value.
    pub const fn get(self) -> u64 {
        self.0
    }
}

impl From<u64> for KeyOrdinal {
    fn from(value: u64) -> Self {
        Self::new(value)
    }
}

impl From<KeyOrdinal> for u64 {
    fn from(value: KeyOrdinal) -> Self {
        value.get()
    }
}

/// Raw MDict encryption bit flags from the header metadata.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct EncryptionMode(pub u8);

impl EncryptionMode {
    pub fn has_keyword_header(self) -> bool {
        self.0 & 0b01 != 0
    }

    pub fn has_keyword_index(self) -> bool {
        self.0 & 0b10 != 0
    }
}

/// Parsed top-level XML metadata from an MDict file.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Header {
    pub raw_xml: String,
    pub tag_name: String,
    pub attributes: BTreeMap<String, String>,
    pub generated_by_engine_version: String,
    pub required_engine_version: String,
    pub encoding_label: Option<String>,
    pub format: Option<String>,
    pub key_case_sensitive: bool,
    pub strip_key: bool,
    pub encrypted: u8,
    pub register_by: Option<String>,
    pub reg_code: Option<String>,
    pub description: Option<String>,
    pub title: Option<String>,
    pub creation_date: Option<String>,
}

impl Header {
    /// Returns the interpreted encryption flags from the header.
    pub fn encryption_mode(&self) -> EncryptionMode {
        EncryptionMode(self.encrypted)
    }

    /// Returns `true` when the dictionary declares a version 2.x engine.
    pub fn is_v2(&self) -> bool {
        self.generated_by_engine_version
            .split('.')
            .next()
            .and_then(|v| v.parse::<u32>().ok())
            .unwrap_or(0)
            >= 2
    }
}

/// Passcode material for dictionaries that encrypt the keyword header.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Passcode {
    pub reg_code_hex: String,
    pub user_id: String,
}

/// Options used when opening an MDX or MDD file.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct OpenOptions {
    pub passcode: Option<Passcode>,
}