1use crate::Value;
2use thiserror::Error as ThisError;
3
4#[derive(Clone, Copy, Debug)]
5#[repr(u32)]
6pub enum Variant {
7 Null = 0,
8 String = 1,
9 Bool = 2,
10 U64 = 3,
11 I64 = 4,
12 F64 = 5,
13 Decimal = 6,
14 I128 = 7,
15 U128 = 8,
16 B32 = 9,
17 B64 = 10,
18 Bytes = 11,
19 Array = 12,
20 Map = 13,
21}
22
23impl Variant {
24 pub const MIN: u32 = 0;
25 pub const MAX: u32 = 13;
26
27 pub const fn variant(&self) -> (u32, &'static str) {
28 let idx = *self as u32;
29 (idx, keys::ALL[idx as usize])
30 }
31}
32
33#[derive(Debug, ThisError)]
34#[error("invalid variant: {}", .0)]
35pub struct InvalidVariant(u32);
36
37impl TryFrom<u32> for Variant {
38 type Error = InvalidVariant;
39
40 fn try_from(v: u32) -> Result<Self, Self::Error> {
41 const VALUES: &[Variant] = &[
42 Variant::Null,
43 Variant::String,
44 Variant::Bool,
45 Variant::U64,
46 Variant::I64,
47 Variant::F64,
48 Variant::Decimal,
49 Variant::I128,
50 Variant::U128,
51 Variant::B32,
52 Variant::B64,
53 Variant::Bytes,
54 Variant::Array,
55 Variant::Map,
56 ];
57 VALUES.get(v as usize).copied().ok_or(InvalidVariant(v))
58 }
59}
60
61pub mod keys {
62 pub const NULL: &str = "N";
63 pub const STRING: &str = "S";
64 pub const BOOL: &str = "B";
65 pub const U64: &str = "U";
66 pub const I64: &str = "I";
67 pub const F64: &str = "F";
68 pub const DECIMAL: &str = "D";
69 pub const I128: &str = "I1";
70 pub const U128: &str = "U1";
71 pub const B32: &str = "B3";
72 pub const B64: &str = "B6";
73 pub const BYTES: &str = "BY";
74 pub const ARRAY: &str = "A";
75 pub const MAP: &str = "M";
76
77 pub const ALL: &[&str] = &[
78 NULL, STRING, BOOL, U64, I64, F64, DECIMAL, I128, U128, B32, B64, BYTES, ARRAY, MAP,
79 ];
80}
81
82struct ValueTypeVisitor;
83
84impl serde::de::Visitor<'_> for ValueTypeVisitor {
85 type Value = Variant;
86
87 fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
88 f.write_str("Variant")
89 }
90
91 fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
92 where
93 E: serde::de::Error,
94 {
95 Self::Value::try_from(v).map_err(serde::de::Error::custom)
96 }
97
98 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
99 where
100 E: serde::de::Error,
101 {
102 Ok(match v {
103 keys::NULL => Variant::Null,
104 keys::STRING => Variant::String,
105 keys::BOOL => Variant::Bool,
106 keys::U64 => Variant::U64,
107 keys::I64 => Variant::I64,
108 keys::F64 => Variant::F64,
109 keys::DECIMAL => Variant::Decimal,
110 keys::I128 => Variant::I128,
111 keys::U128 => Variant::U128,
112 keys::B32 => Variant::B32,
113 keys::B64 => Variant::B64,
114 keys::BYTES => Variant::Bytes,
115 keys::ARRAY => Variant::Array,
116 keys::MAP => Variant::Map,
117 _ => {
118 return Err(serde::de::Error::invalid_value(
119 serde::de::Unexpected::Str(v),
120 &"one of valid keys",
121 ));
122 }
123 })
124 }
125}
126
127impl<'de> serde::Deserialize<'de> for Variant {
128 fn deserialize<D>(d: D) -> Result<Self, D::Error>
129 where
130 D: serde::Deserializer<'de>,
131 {
132 if d.is_human_readable() {
133 d.deserialize_str(ValueTypeVisitor)
134 } else {
135 d.deserialize_u32(ValueTypeVisitor)
136 }
137 }
138}
139
140impl Value {
141 pub const fn kind(&self) -> Variant {
142 match self {
143 Value::Null => Variant::Null,
144 Value::String(_) => Variant::String,
145 Value::Bool(_) => Variant::Bool,
146 Value::U64(_) => Variant::U64,
147 Value::I64(_) => Variant::I64,
148 Value::F64(_) => Variant::F64,
149 Value::Decimal(_) => Variant::Decimal,
150 Value::I128(_) => Variant::I128,
151 Value::U128(_) => Variant::U128,
152 Value::B32(_) => Variant::B32,
153 Value::B64(_) => Variant::B64,
154 Value::Bytes(_) => Variant::Bytes,
155 Value::Array(_) => Variant::Array,
156 Value::Map(_) => Variant::Map,
157 }
158 }
159}