ion_rs/binary/
type_code.rs

1use std::convert::TryFrom;
2
3use crate::result::{decoding_error, IonError};
4use crate::types::IonType;
5
6/// Represents the type information found in the header byte of each binary Ion value.
7/// While this value can be readily mapped to a user-level [`IonType`], it is a distinct concept.
8/// The IonTypeCode enum captures system-level information that is not exposed to end users of the
9/// library, including:
10/// * Whether the cursor is positioned over whitespace that needs to be skipped.
11/// * Whether the integer value being read is positive or negative.
12/// * Whether the next type code is reserved.
13///
14/// See the
15/// [Typed Value Formats](https://amazon-ion.github.io/ion-docs/docs/binary.html#typed-value-formats)
16/// section of the spec for more information.
17#[derive(Debug, PartialEq, Eq, Copy, Clone)]
18pub enum IonTypeCode {
19    NullOrNop,       // 0
20    Boolean,         // 1
21    PositiveInteger, // 2
22    NegativeInteger, // 3
23    Float,           // 4
24    Decimal,         // 5
25    Timestamp,       // 6
26    Symbol,          // 7
27    String,          // 8
28    Clob,            // 9
29    Blob,            // 10
30    List,            // 11
31    SExpression,     // 12
32    Struct,          // 13
33    AnnotationOrIvm, // 14
34    Reserved,        // 15
35}
36
37impl TryFrom<IonTypeCode> for IonType {
38    type Error = IonError;
39
40    /// Attempts to convert the system-level IonTypeCode into the corresponding user-level IonType.
41    fn try_from(ion_type_code: IonTypeCode) -> Result<Self, Self::Error> {
42        use IonTypeCode::*;
43        let ion_type = match ion_type_code {
44            NullOrNop => IonType::Null,
45            Boolean => IonType::Bool,
46            PositiveInteger | NegativeInteger => IonType::Int,
47            Float => IonType::Float,
48            Decimal => IonType::Decimal,
49            Timestamp => IonType::Timestamp,
50            Symbol => IonType::Symbol,
51            String => IonType::String,
52            Clob => IonType::Clob,
53            Blob => IonType::Blob,
54            List => IonType::List,
55            SExpression => IonType::SExp,
56            Struct => IonType::Struct,
57            _ => {
58                return decoding_error(format!(
59                    "Attempted to make an IonType from an invalid type code: {ion_type_code:?}"
60                ));
61            }
62        };
63        Ok(ion_type)
64    }
65}
66
67impl TryFrom<u8> for IonTypeCode {
68    type Error = IonError;
69
70    /// Attempts to convert the provided byte into an IonTypeCode. Any value greater than 15
71    /// will result in an Error.
72    fn try_from(type_code: u8) -> Result<Self, Self::Error> {
73        use IonTypeCode::*;
74        let ion_type_code = match type_code {
75            0 => NullOrNop,
76            1 => Boolean,
77            2 => PositiveInteger,
78            3 => NegativeInteger,
79            4 => Float,
80            5 => Decimal,
81            6 => Timestamp,
82            7 => Symbol,
83            8 => String,
84            9 => Clob,
85            10 => Blob,
86            11 => List,
87            12 => SExpression,
88            13 => Struct,
89            14 => AnnotationOrIvm,
90            15 => Reserved,
91            _ => {
92                return decoding_error(format!("{type_code:?} is not a valid header type code."));
93            }
94        };
95        Ok(ion_type_code)
96    }
97}
98
99impl IonTypeCode {
100    /// Constant function to convert an [`IonTypeCode`] into a `u8`.
101    pub const fn to_u8(self) -> u8 {
102        use IonTypeCode::*;
103        match self {
104            NullOrNop => 0,
105            Boolean => 1,
106            PositiveInteger => 2,
107            NegativeInteger => 3,
108            Float => 4,
109            Decimal => 5,
110            Timestamp => 6,
111            Symbol => 7,
112            String => 8,
113            Clob => 9,
114            Blob => 10,
115            List => 11,
116            SExpression => 12,
117            Struct => 13,
118            AnnotationOrIvm => 14,
119            Reserved => 15,
120        }
121    }
122}