dxfscan 0.1.0

Binary DXF parser with typed entity data and lookup indices
Documentation
// SPDX-License-Identifier: ISC
use super::Attrib;
use crate::point::Point3;
use crate::value::GroupValue;
use alloc::vec::Vec;

/// An INSERT (block reference) entity.
///
/// Child ATTRIB entities are collected in `attributes` when
/// `has_attributes` is true.
#[derive(Debug, Clone, Default)]
pub struct Insert<'a> {
    /// Block name.
    pub name: &'a [u8],
    /// Insertion point.
    pub location: Point3,
    /// X scale factor.
    ///
    /// Defaults to 1.0.
    pub x_scale: f64,
    /// Y scale factor.
    ///
    /// Defaults to 1.0.
    pub y_scale: f64,
    /// Z scale factor.
    ///
    /// Defaults to 1.0.
    pub z_scale: f64,
    /// Rotation angle in degrees.
    pub rotation: f64,
    /// Row count for array inserts.
    ///
    /// Defaults to 1.
    pub row_count: i16,
    /// Column count for array inserts.
    ///
    /// Defaults to 1.
    pub column_count: i16,
    /// Row spacing.
    pub row_spacing: f64,
    /// Column spacing.
    pub column_spacing: f64,
    /// Whether this insert has child ATTRIB entities.
    ///
    /// When true, the DXF file contains ATTRIB entities between
    /// this INSERT and a terminating SEQEND. The scanner collects
    /// them into `attributes` automatically.
    pub has_attributes: bool,
    /// Child ATTRIB entities collected between INSERT and SEQEND.
    pub attributes: Vec<Attrib<'a>>,
}

impl<'a> Insert<'a> {
    pub(crate) fn new() -> Self {
        Self {
            x_scale: 1.0,
            y_scale: 1.0,
            z_scale: 1.0,
            row_count: 1,
            column_count: 1,
            ..Default::default()
        }
    }

    pub(crate) fn feed(&mut self, code: u16, val: &GroupValue<'a>) {
        match code {
            2 => {
                if let Some(s) = val.as_str_bytes() {
                    self.name = s;
                }
            }
            66 => {
                if let Some(v) = val.as_i16() {
                    self.has_attributes = v != 0;
                }
            }
            70 => {
                if let Some(v) = val.as_i16() {
                    self.column_count = v;
                }
            }
            71 => {
                if let Some(v) = val.as_i16() {
                    self.row_count = v;
                }
            }
            _ => {
                if let Some(v) = val.as_f64() {
                    match code {
                        10 => self.location.x = v,
                        20 => self.location.y = v,
                        30 => self.location.z = v,
                        41 => self.x_scale = v,
                        42 => self.y_scale = v,
                        43 => self.z_scale = v,
                        44 => self.column_spacing = v,
                        45 => self.row_spacing = v,
                        50 => self.rotation = v,
                        _ => {}
                    }
                }
            }
        }
    }
}