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}