dxfscan 0.1.0

Binary DXF parser with typed entity data and lookup indices
Documentation
// SPDX-License-Identifier: ISC
use crate::block::Block;
use crate::entity::Entity;
use crate::table::{Layer, Style};
use crate::value::GroupValue;
use alloc::collections::BTreeMap;
use alloc::vec::Vec;

/// The top-level result of scanning a binary DXF file.
///
/// Contains all parsed sections (header variables, tables, blocks,
/// and model-space entities) along with lookup indices for fast
/// access by name or handle. All string data borrows from the
/// input byte slice.
#[derive(Debug, Default)]
pub struct Drawing<'a> {
    /// Header variables from the HEADER section.
    ///
    /// Keys are variable names (e.g. `"$ACADVER"`). Values are the
    /// first group code/value pair following each variable name.
    /// Multi-component variables (such as points) store only their
    /// first component.
    pub headers: BTreeMap<&'a str, GroupValue<'a>>,
    /// Model-space entities, in file order.
    pub entities: Vec<Entity<'a>>,
    /// All layer definitions.
    pub layers: Vec<Layer<'a>>,
    /// All text style definitions.
    pub styles: Vec<Style<'a>>,
    /// All block definitions.
    pub blocks: Vec<Block<'a>>,

    /// Layer name → index into `layers`.
    pub layers_by_name: BTreeMap<&'a [u8], usize>,
    /// Style name → index into `styles`.
    pub styles_by_name: BTreeMap<&'a [u8], usize>,
    /// Block name → index into `blocks`.
    pub blocks_by_name: BTreeMap<&'a [u8], usize>,
    /// Entity handle (hex string bytes) → index into `entities`.
    pub entity_by_handle: BTreeMap<&'a [u8], usize>,
}

impl<'a> Drawing<'a> {
    /// Looks up a header variable by name (e.g. `"$ACADVER"`).
    pub fn header(&self, name: &str) -> Option<&GroupValue<'a>> {
        self.headers.get(name)
    }

    /// Looks up a layer by name.
    pub fn layer_by_name(&self, name: &[u8]) -> Option<&Layer<'a>> {
        self.layers_by_name.get(name).map(|&i| &self.layers[i])
    }

    /// Looks up a text style by name.
    pub fn style_by_name(&self, name: &[u8]) -> Option<&Style<'a>> {
        self.styles_by_name.get(name).map(|&i| &self.styles[i])
    }

    /// Looks up a block definition by name.
    pub fn block_by_name(&self, name: &[u8]) -> Option<&Block<'a>> {
        self.blocks_by_name.get(name).map(|&i| &self.blocks[i])
    }

    /// Looks up a model-space entity by its handle (hex string bytes).
    pub fn entity_by_handle(&self, handle: &[u8]) -> Option<&Entity<'a>> {
        self.entity_by_handle
            .get(handle)
            .map(|&i| &self.entities[i])
    }
}