Skip to main content

tpack_core/
value.rs

1use alloc::{borrow::Cow, vec::Vec};
2
3use crate::{CalendarInterval, Decimal, Duration};
4
5#[derive(Debug, Clone, PartialEq)]
6pub enum TpackValue<'de> {
7    Null,
8    Bool(bool),
9    I8(i8),
10    I16(i16),
11    I32(i32),
12    I64(i64),
13    U8(u8),
14    U16(u16),
15    U32(u32),
16    U64(u64),
17    F32(f32),
18    F64(f64),
19    Decimal(Decimal),
20    DecimalFixed(i64),
21    String(Cow<'de, str>),
22    Bytes(Cow<'de, [u8]>),
23    Date(i64),
24    Time(u64),
25    DateTime {
26        days: i64,
27        nanos: u64,
28    },
29    DateTimeTz {
30        days: i64,
31        nanos: u64,
32        timezone: Cow<'de, str>,
33    },
34    Timestamp(i64),
35    Duration(Duration),
36    BigInt(i64),
37    BigUInt(u64),
38    CalendarInterval(CalendarInterval),
39    Struct(Vec<(u64, TpackValue<'de>)>),
40    List(Vec<TpackValue<'de>>),
41    Map(Vec<ValueMapEntry<'de>>),
42    Union {
43        index: u64,
44        value: alloc::boxed::Box<TpackValue<'de>>,
45    },
46    Enum(u64),
47    Optional(Option<alloc::boxed::Box<TpackValue<'de>>>),
48    Extension(Cow<'de, [u8]>),
49}
50
51#[derive(Debug, Clone, PartialEq)]
52pub struct ValueMapEntry<'de> {
53    pub key: TpackValue<'de>,
54    pub value: TpackValue<'de>,
55}
56
57impl<'de> TpackValue<'de> {
58    pub fn is_composite(&self) -> bool {
59        matches!(
60            self,
61            Self::Struct(_)
62                | Self::List(_)
63                | Self::Map(_)
64                | Self::Union { .. }
65                | Self::Optional(Some(_))
66        )
67    }
68
69    pub fn into_owned(self) -> TpackValue<'static> {
70        match self {
71            TpackValue::Null => TpackValue::Null,
72            TpackValue::Bool(v) => TpackValue::Bool(v),
73            TpackValue::I8(v) => TpackValue::I8(v),
74            TpackValue::I16(v) => TpackValue::I16(v),
75            TpackValue::I32(v) => TpackValue::I32(v),
76            TpackValue::I64(v) => TpackValue::I64(v),
77            TpackValue::U8(v) => TpackValue::U8(v),
78            TpackValue::U16(v) => TpackValue::U16(v),
79            TpackValue::U32(v) => TpackValue::U32(v),
80            TpackValue::U64(v) => TpackValue::U64(v),
81            TpackValue::F32(v) => TpackValue::F32(v),
82            TpackValue::F64(v) => TpackValue::F64(v),
83            TpackValue::Decimal(v) => TpackValue::Decimal(v),
84            TpackValue::DecimalFixed(v) => TpackValue::DecimalFixed(v),
85            TpackValue::String(v) => TpackValue::String(Cow::Owned(v.into_owned())),
86            TpackValue::Bytes(v) => TpackValue::Bytes(Cow::Owned(v.into_owned())),
87            TpackValue::Date(v) => TpackValue::Date(v),
88            TpackValue::Time(v) => TpackValue::Time(v),
89            TpackValue::DateTime { days, nanos } => TpackValue::DateTime { days, nanos },
90            TpackValue::DateTimeTz {
91                days,
92                nanos,
93                timezone,
94            } => TpackValue::DateTimeTz {
95                days,
96                nanos,
97                timezone: Cow::Owned(timezone.into_owned()),
98            },
99            TpackValue::Timestamp(v) => TpackValue::Timestamp(v),
100            TpackValue::Duration(v) => TpackValue::Duration(v),
101            TpackValue::BigInt(v) => TpackValue::BigInt(v),
102            TpackValue::BigUInt(v) => TpackValue::BigUInt(v),
103            TpackValue::CalendarInterval(v) => TpackValue::CalendarInterval(v),
104            TpackValue::Struct(fields) => TpackValue::Struct(
105                fields
106                    .into_iter()
107                    .map(|(id, value)| (id, value.into_owned()))
108                    .collect(),
109            ),
110            TpackValue::List(items) => {
111                TpackValue::List(items.into_iter().map(TpackValue::into_owned).collect())
112            }
113            TpackValue::Map(entries) => TpackValue::Map(
114                entries
115                    .into_iter()
116                    .map(|entry| ValueMapEntry {
117                        key: entry.key.into_owned(),
118                        value: entry.value.into_owned(),
119                    })
120                    .collect(),
121            ),
122            TpackValue::Union { index, value } => TpackValue::Union {
123                index,
124                value: alloc::boxed::Box::new(value.into_owned()),
125            },
126            TpackValue::Enum(index) => TpackValue::Enum(index),
127            TpackValue::Optional(value) => {
128                TpackValue::Optional(value.map(|value| alloc::boxed::Box::new(value.into_owned())))
129            }
130            TpackValue::Extension(value) => TpackValue::Extension(Cow::Owned(value.into_owned())),
131        }
132    }
133}