dxfbin 0.1.0

Streaming text DXF to binary DXF converter
Documentation
// SPDX-License-Identifier: ISC
/// The binary encoding type of a DXF group code's value.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ValueType {
    /// Null-terminated byte string.
    String,
    /// Single-byte boolean (`0` or `1`).
    Boolean,
    /// 16-bit signed integer, little-endian.
    Int16,
    /// 32-bit signed integer, little-endian.
    Int32,
    /// 64-bit signed integer, little-endian.
    Int64,
    /// IEEE 754 double-precision float, little-endian.
    Double,
    /// Length-prefixed raw byte chunk (hex-encoded in text DXF).
    BinaryChunk,
}

/// Returns the [`ValueType`] for a DXF group code.
///
/// Unknown codes default to [`ValueType::String`].
pub fn value_type_of(code: u16) -> ValueType {
    match code {
        0..=9 => ValueType::String,
        10..=59 => ValueType::Double,
        60..=89 => ValueType::Int16,
        90..=99 => ValueType::Int32,
        100..=109 => ValueType::String,
        110..=159 => ValueType::Double,
        160..=169 => ValueType::Int64,
        170..=189 => ValueType::Int16,
        210..=239 => ValueType::Double,
        260..=289 => ValueType::Int16,
        290..=299 => ValueType::Boolean,
        300..=309 => ValueType::String,
        310..=319 => ValueType::BinaryChunk,
        320..=369 => ValueType::String,
        370..=389 => ValueType::Int16,
        390..=399 => ValueType::String,
        400..=409 => ValueType::Int16,
        410..=419 => ValueType::String,
        420..=429 => ValueType::Int32,
        430..=439 => ValueType::String,
        440..=459 => ValueType::Int32,
        460..=469 => ValueType::Double,
        470..=479 => ValueType::String,
        480..=489 => ValueType::String,
        999 => ValueType::String,
        1000..=1003 => ValueType::String,
        1004 => ValueType::BinaryChunk,
        1005..=1009 => ValueType::String,
        1010..=1059 => ValueType::Double,
        1060..=1070 => ValueType::Int16,
        1071 => ValueType::Int32,
        _ => ValueType::String,
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn string_ranges() {
        for code in [
            0, 5, 9, 100, 105, 109, 300, 309, 320, 369, 390, 399, 410, 419, 430, 439, 470, 479,
            480, 489, 999, 1000, 1003, 1005, 1009,
        ] {
            assert_eq!(value_type_of(code), ValueType::String, "code {code}");
        }
    }

    #[test]
    fn double_ranges() {
        for code in [
            10, 39, 40, 59, 110, 149, 150, 159, 210, 239, 460, 469, 1010, 1059,
        ] {
            assert_eq!(value_type_of(code), ValueType::Double, "code {code}");
        }
    }

    #[test]
    fn int16_ranges() {
        for code in [
            60, 79, 80, 89, 170, 179, 180, 189, 260, 269, 270, 279, 280, 289, 370, 379, 380, 389,
            400, 409, 1060, 1070,
        ] {
            assert_eq!(value_type_of(code), ValueType::Int16, "code {code}");
        }
    }

    #[test]
    fn int32_ranges() {
        for code in [90, 99, 420, 429, 440, 449, 450, 459, 1071] {
            assert_eq!(value_type_of(code), ValueType::Int32, "code {code}");
        }
    }

    #[test]
    fn int64_range() {
        for code in [160, 169] {
            assert_eq!(value_type_of(code), ValueType::Int64, "code {code}");
        }
    }

    #[test]
    fn boolean_range() {
        for code in [290, 299] {
            assert_eq!(value_type_of(code), ValueType::Boolean, "code {code}");
        }
    }

    #[test]
    fn binary_chunk_ranges() {
        for code in [310, 319, 1004] {
            assert_eq!(value_type_of(code), ValueType::BinaryChunk, "code {code}");
        }
    }

    #[test]
    fn unknown_defaults_to_string() {
        assert_eq!(value_type_of(255), ValueType::String);
        assert_eq!(value_type_of(5000), ValueType::String);
    }
}