1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//! Node attribute type.

use std::io;

use crate::pull_parser::{error::DataError, v7400::FromReader, Error as ParserError};

/// Node attribute type.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AttributeType {
    /// Single `bool`.
    Bool,
    /// Single `i16`.
    I16,
    /// Single `i32`.
    I32,
    /// Single `i64`.
    I64,
    /// Single `f32`.
    F32,
    /// Single `f64`.
    F64,
    /// Array of `bool`.
    ArrBool,
    /// Array of `i32`.
    ArrI32,
    /// Array of `i64`.
    ArrI64,
    /// Array of `f32`.
    ArrF32,
    /// Array of `f64`.
    ArrF64,
    /// Binary.
    Binary,
    /// UTF-8 string.
    String,
}

impl AttributeType {
    /// Creates an `AttributeType` from the given type code.
    pub(crate) fn from_type_code(code: u8) -> Option<Self> {
        match code {
            b'C' => Some(AttributeType::Bool),
            b'Y' => Some(AttributeType::I16),
            b'I' => Some(AttributeType::I32),
            b'L' => Some(AttributeType::I64),
            b'F' => Some(AttributeType::F32),
            b'D' => Some(AttributeType::F64),
            b'b' => Some(AttributeType::ArrBool),
            b'i' => Some(AttributeType::ArrI32),
            b'l' => Some(AttributeType::ArrI64),
            b'f' => Some(AttributeType::ArrF32),
            b'd' => Some(AttributeType::ArrF64),
            b'R' => Some(AttributeType::Binary),
            b'S' => Some(AttributeType::String),
            _ => None,
        }
    }
}

impl FromReader for AttributeType {
    fn from_reader(reader: &mut impl io::Read) -> Result<Self, ParserError> {
        let type_code = u8::from_reader(reader)?;
        let attr_type = Self::from_type_code(type_code)
            .ok_or_else(|| DataError::InvalidAttributeTypeCode(type_code))?;
        Ok(attr_type)
    }
}