1use faststr::FastStr;
2use serde::ser::{Serialize, Serializer};
3use smallvec::SmallVec;
4
5use crate::key::Key;
6use crate::wide_event::WideEvent;
7
8#[derive(Debug, Clone)]
28pub enum Value<K: Key> {
29 Null,
31 Bool(bool),
33 I64(i64),
35 U64(u64),
37 F64(f64),
39 String(FastStr),
41 Array(SmallVec<[Box<Value<K>>; 8]>),
43 Object(Box<WideEvent<K>>),
47}
48
49impl<K: Key> Serialize for Value<K> {
50 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
51 match self {
52 Value::Null => serializer.serialize_unit(),
53 Value::Bool(b) => serializer.serialize_bool(*b),
54 Value::I64(n) => serializer.serialize_i64(*n),
55 Value::U64(n) => serializer.serialize_u64(*n),
56 Value::F64(n) => serializer.serialize_f64(*n),
57 Value::String(s) => serializer.serialize_str(s.as_str()),
58 Value::Array(arr) => arr.serialize(serializer),
59 Value::Object(obj) => obj.serialize(serializer),
60 }
61 }
62}
63
64impl<K: Key> From<bool> for Value<K> {
65 #[inline]
66 fn from(b: bool) -> Self {
67 Value::Bool(b)
68 }
69}
70
71impl<K: Key> From<i64> for Value<K> {
72 #[inline]
73 fn from(n: i64) -> Self {
74 Value::I64(n)
75 }
76}
77
78impl<K: Key> From<u64> for Value<K> {
79 #[inline]
80 fn from(n: u64) -> Self {
81 Value::U64(n)
82 }
83}
84
85impl<K: Key> From<f64> for Value<K> {
86 #[inline]
87 fn from(n: f64) -> Self {
88 Value::F64(n)
89 }
90}
91
92impl<K: Key> From<&str> for Value<K> {
93 #[inline]
94 fn from(s: &str) -> Self {
95 Value::String(FastStr::new(s))
96 }
97}
98
99impl<K: Key> From<String> for Value<K> {
100 #[inline]
101 fn from(s: String) -> Self {
102 Value::String(FastStr::new(&s))
103 }
104}
105
106impl<K: Key> From<FastStr> for Value<K> {
107 #[inline]
108 fn from(s: FastStr) -> Self {
109 Value::String(s)
110 }
111}
112
113impl<K: Key> From<()> for Value<K> {
114 #[inline]
115 fn from(_: ()) -> Self {
116 Value::Null
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123 use crate::key::test_support::TestKey;
124
125 #[test]
126 fn from_bool() {
127 assert!(matches!(Value::<TestKey>::from(true), Value::Bool(true)));
128 assert!(matches!(Value::<TestKey>::from(false), Value::Bool(false)));
129 }
130
131 #[test]
132 fn from_i64() {
133 assert!(matches!(Value::<TestKey>::from(-42i64), Value::I64(-42)));
134 }
135
136 #[test]
137 fn from_u64() {
138 assert!(matches!(Value::<TestKey>::from(99u64), Value::U64(99)));
139 }
140
141 #[test]
142 fn from_f64() {
143 assert!(matches!(Value::<TestKey>::from(3.15f64), Value::F64(_)));
144 }
145
146 #[test]
147 fn from_str_is_string() {
148 assert!(matches!(Value::<TestKey>::from("hello"), Value::String(_)));
149 }
150
151 #[test]
152 fn from_owned_string_is_string() {
153 assert!(matches!(
154 Value::<TestKey>::from("world".to_string()),
155 Value::String(_)
156 ));
157 }
158
159 #[test]
160 fn from_unit_is_null() {
161 assert!(matches!(Value::<TestKey>::from(()), Value::Null));
162 }
163
164 #[test]
165 fn serialize_null() {
166 let v = Value::<TestKey>::from(());
167 let s = sonic_rs::to_string(&v).unwrap();
168 assert_eq!(s, "null");
169 }
170
171 #[test]
172 fn serialize_scalars() {
173 assert_eq!(
174 sonic_rs::to_string(&Value::<TestKey>::from(true)).unwrap(),
175 "true"
176 );
177 assert_eq!(
178 sonic_rs::to_string(&Value::<TestKey>::from(false)).unwrap(),
179 "false"
180 );
181 assert_eq!(
182 sonic_rs::to_string(&Value::<TestKey>::from(-7i64)).unwrap(),
183 "-7"
184 );
185 assert_eq!(
186 sonic_rs::to_string(&Value::<TestKey>::from(42u64)).unwrap(),
187 "42"
188 );
189 assert_eq!(
190 sonic_rs::to_string(&Value::<TestKey>::from("hi")).unwrap(),
191 "\"hi\""
192 );
193 }
194
195 #[test]
196 fn serialize_array() {
197 let arr: SmallVec<[Box<Value<TestKey>>; 8]> =
198 smallvec::smallvec![Box::new(Value::from(1i64)), Box::new(Value::from(2i64)),];
199 let v = Value::<TestKey>::Array(arr);
200 assert_eq!(sonic_rs::to_string(&v).unwrap(), "[1,2]");
201 }
202}