Skip to main content

mcap2arrow_core/
value.rs

1//! Type-safe intermediate representation produced by message decoders.
2
3use std::sync::Arc;
4
5use crate::error::ValueTypeError;
6
7/// Value produced by message decoders.
8/// All types are explicit; no lossy conversions.
9#[derive(Debug, Clone)]
10pub enum Value {
11    Null,
12    Bool(bool),
13    I8(i8),
14    I16(i16),
15    I32(i32),
16    I64(i64),
17    U8(u8),
18    U16(u16),
19    U32(u32),
20    U64(u64),
21    F32(f32),
22    F64(f64),
23    String(Arc<str>),
24    Bytes(Arc<[u8]>),
25    Struct(Vec<Value>),
26    List(Vec<Value>),
27    Array(Vec<Value>),
28    Map(Vec<(Value, Value)>),
29}
30
31impl Value {
32    pub fn string(s: impl AsRef<str>) -> Self {
33        Self::String(Arc::from(s.as_ref()))
34    }
35
36    pub fn try_i8(&self) -> Result<Option<i8>, ValueTypeError> {
37        match self {
38            Value::I8(v) => Ok(Some(*v)),
39            Value::Null => Ok(None),
40            _ => Err(self.type_mismatch("I8")),
41        }
42    }
43
44    pub fn try_i16(&self) -> Result<Option<i16>, ValueTypeError> {
45        match self {
46            Value::I16(v) => Ok(Some(*v)),
47            Value::Null => Ok(None),
48            _ => Err(self.type_mismatch("I16")),
49        }
50    }
51
52    pub fn try_i32(&self) -> Result<Option<i32>, ValueTypeError> {
53        match self {
54            Value::I32(v) => Ok(Some(*v)),
55            Value::Null => Ok(None),
56            _ => Err(self.type_mismatch("I32")),
57        }
58    }
59
60    pub fn try_i64(&self) -> Result<Option<i64>, ValueTypeError> {
61        match self {
62            Value::I64(v) => Ok(Some(*v)),
63            Value::Null => Ok(None),
64            _ => Err(self.type_mismatch("I64")),
65        }
66    }
67
68    pub fn try_u8(&self) -> Result<Option<u8>, ValueTypeError> {
69        match self {
70            Value::U8(v) => Ok(Some(*v)),
71            Value::Null => Ok(None),
72            _ => Err(self.type_mismatch("U8")),
73        }
74    }
75
76    pub fn try_u16(&self) -> Result<Option<u16>, ValueTypeError> {
77        match self {
78            Value::U16(v) => Ok(Some(*v)),
79            Value::Null => Ok(None),
80            _ => Err(self.type_mismatch("U16")),
81        }
82    }
83
84    pub fn try_u32(&self) -> Result<Option<u32>, ValueTypeError> {
85        match self {
86            Value::U32(v) => Ok(Some(*v)),
87            Value::Null => Ok(None),
88            _ => Err(self.type_mismatch("U32")),
89        }
90    }
91
92    pub fn try_u64(&self) -> Result<Option<u64>, ValueTypeError> {
93        match self {
94            Value::U64(v) => Ok(Some(*v)),
95            Value::Null => Ok(None),
96            _ => Err(self.type_mismatch("U64")),
97        }
98    }
99
100    pub fn try_bool(&self) -> Result<Option<bool>, ValueTypeError> {
101        match self {
102            Value::Bool(v) => Ok(Some(*v)),
103            Value::Null => Ok(None),
104            _ => Err(self.type_mismatch("Bool")),
105        }
106    }
107
108    pub fn try_f32(&self) -> Result<Option<f32>, ValueTypeError> {
109        match self {
110            Value::F32(v) => Ok(Some(*v)),
111            Value::Null => Ok(None),
112            _ => Err(self.type_mismatch("F32")),
113        }
114    }
115
116    pub fn try_f64(&self) -> Result<Option<f64>, ValueTypeError> {
117        match self {
118            Value::F64(v) => Ok(Some(*v)),
119            Value::Null => Ok(None),
120            _ => Err(self.type_mismatch("F64")),
121        }
122    }
123
124    pub fn try_str(&self) -> Result<Option<&str>, ValueTypeError> {
125        match self {
126            Value::String(v) => Ok(Some(v.as_ref())),
127            Value::Null => Ok(None),
128            _ => Err(self.type_mismatch("String")),
129        }
130    }
131
132    pub fn try_bytes(&self) -> Result<Option<&[u8]>, ValueTypeError> {
133        match self {
134            Value::Bytes(v) => Ok(Some(v.as_ref())),
135            Value::Null => Ok(None),
136            _ => Err(self.type_mismatch("Bytes")),
137        }
138    }
139
140    pub fn type_mismatch(&self, expected: impl Into<String>) -> ValueTypeError {
141        ValueTypeError::new(expected, self.variant_name())
142    }
143
144    fn variant_name(&self) -> &'static str {
145        match self {
146            Value::Null => "Null",
147            Value::Bool(_) => "Bool",
148            Value::I8(_) => "I8",
149            Value::I16(_) => "I16",
150            Value::I32(_) => "I32",
151            Value::I64(_) => "I64",
152            Value::U8(_) => "U8",
153            Value::U16(_) => "U16",
154            Value::U32(_) => "U32",
155            Value::U64(_) => "U64",
156            Value::F32(_) => "F32",
157            Value::F64(_) => "F64",
158            Value::String(_) => "String",
159            Value::Bytes(_) => "Bytes",
160            Value::Struct(_) => "Struct",
161            Value::List(_) => "List",
162            Value::Array(_) => "Array",
163            Value::Map(_) => "Map",
164        }
165    }
166}