1mod convert;
2mod de;
3mod error;
4mod from;
5mod ser;
6
7use std::fmt::{Debug, Display};
8
9use indexmap::IndexMap;
10use serde::de::DeserializeOwned;
11use serde::ser::Serialize;
12
13use crate::{Function, Number};
14
15pub use self::convert::convert;
16pub use self::error::SerdeValueError;
17
18use self::ser::Serializer;
19
20pub type SerdeValueList = Vec<SerdeValue>;
21pub type SerdeValueObject = IndexMap<String, SerdeValue>;
22
23#[derive(Default, Clone, PartialEq)]
24pub enum SerdeValue {
25 #[default]
26 Null,
27 Boolean(bool),
28 String(String),
29 Number(Number),
30 Function(Function),
31 List(SerdeValueList),
32 Object(SerdeValueObject),
33}
34
35pub fn to_serde_value<T>(value: T) -> Result<SerdeValue, SerdeValueError>
36where
37 T: Serialize,
38{
39 value.serialize(Serializer)
40}
41
42pub fn from_serde_value<T>(value: SerdeValue) -> Result<T, SerdeValueError>
43where
44 T: DeserializeOwned,
45{
46 T::deserialize(value)
47}
48
49impl Debug for SerdeValue {
50 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 match self {
52 SerdeValue::Null => formatter.write_str("Null"),
53 SerdeValue::Boolean(boolean) => match boolean {
54 true => formatter.write_str("true"),
55 false => formatter.write_str("false"),
56 },
57 SerdeValue::String(string) => write!(formatter, "String({:?})", string),
58 SerdeValue::Number(number) => write!(formatter, "Number({})", number),
59 SerdeValue::Function(function) => {
60 write!(formatter, "Function({:?})", function)
61 }
62 SerdeValue::List(list) => {
63 formatter.write_str("List ")?;
64 formatter.debug_list().entries(list).finish()
65 }
66 SerdeValue::Object(object) => {
67 formatter.write_str("Object ")?;
68 formatter.debug_map().entries(object).finish()
69 }
70 }
71 }
72}
73
74impl Display for SerdeValue {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 match self {
77 SerdeValue::Null => write!(f, "null"),
78 SerdeValue::Boolean(boolean) => write!(f, "{}", boolean),
79 SerdeValue::String(string) => write!(f, "{}", string),
80 SerdeValue::Number(number) => write!(f, "{}", number),
81 SerdeValue::Function(function) => write!(f, "{}", function),
82 SerdeValue::List(list) => {
83 let items = list
84 .iter()
85 .map(|value| value.to_string())
86 .collect::<Vec<String>>()
87 .join(", ");
88 write!(f, "[{}]", items)
89 }
90 SerdeValue::Object(object) => {
91 let entries = object
92 .iter()
93 .map(|(key, value)| format!("\"{}\": {}", key, value))
94 .collect::<Vec<String>>()
95 .join(", ");
96 write!(f, "{{{}}}", entries)
97 }
98 }
99 }
100}
101
102pub fn value_get_in<'a>(value: &'a SerdeValue, keys: &[&str]) -> Option<&'a SerdeValue> {
103 let Some((first, rest)) = keys.split_first() else {
104 return Some(value);
105 };
106 match value {
107 SerdeValue::Object(object) => match object.get(*first) {
108 Some(value) => value_get_in(value, rest),
109 None => None,
110 },
111 _ => None,
112 }
113}
114
115#[cfg(test)]
116mod test {
117 use std::{borrow::Cow, ffi::OsString, path::PathBuf};
118
119 use crate::SerdeValue;
120 use pretty_assertions::assert_eq;
121 use rust_decimal_macros::dec;
122
123 #[test]
124 fn from_string_tests() {
125 assert_eq!(
126 SerdeValue::from("John Sheppard"),
127 SerdeValue::String("John Sheppard".to_string())
128 );
129
130 assert_eq!(
131 SerdeValue::from("Elizabeth Weir".to_string()),
132 SerdeValue::String("Elizabeth Weir".to_string())
133 );
134
135 assert_eq!(
136 SerdeValue::from(PathBuf::new()),
137 SerdeValue::String("".to_string())
138 );
139
140 assert_eq!(
141 SerdeValue::from(Cow::from("Samantha Carter")),
142 SerdeValue::String("Samantha Carter".to_string())
143 );
144
145 assert_eq!(
146 SerdeValue::from(OsString::from("Jennifer Keller")),
147 SerdeValue::String("Jennifer Keller".to_string())
148 );
149 }
150
151 #[test]
152 fn from_vec_test() {
153 assert_eq!(
154 SerdeValue::from(vec!["Aiden Ford", "Rodney McKay", "Ronon Dex"]),
155 SerdeValue::List(vec![
156 SerdeValue::String("Aiden Ford".to_string()),
157 SerdeValue::String("Rodney McKay".to_string()),
158 SerdeValue::String("Ronon Dex".to_string())
159 ])
160 );
161 }
162
163 #[test]
164 fn debug_tests() {
165 assert_eq!(format!("{:?}", SerdeValue::Null), "Null".to_string());
166
167 assert_eq!(
168 format!("{:?}", SerdeValue::String("Richard Woolsey".to_string())),
169 "String(\"Richard Woolsey\")".to_string()
170 );
171
172 assert_eq!(
173 format!(
174 "{:?}",
175 SerdeValue::List(vec![
176 SerdeValue::String("Aiden Ford".to_string()),
177 SerdeValue::String("Rodney McKay".to_string()),
178 SerdeValue::String("Ronon Dex".to_string())
179 ])
180 ),
181 "List [String(\"Aiden Ford\"), String(\"Rodney McKay\"), String(\"Ronon Dex\")]"
182 .to_string()
183 );
184
185 assert_eq!(
186 format!("{:?}", SerdeValue::Number(dec!(2).into())),
187 "Number(2)".to_string()
188 );
189 }
190}