1use serde::{de::DeserializeOwned, Serialize};
2use std::{collections::BTreeMap, fmt::Debug};
3
4use crate::{byte_string::ByteString, Error};
5
6mod de;
7mod integer;
8mod ser;
9
10pub use integer::Integer;
11pub use ser::ValueSerializer;
12
13pub type Dictionary<V = Value> = BTreeMap<ByteString, V>;
14
15#[derive(PartialEq, Eq, PartialOrd, Ord)]
17pub enum Value {
18 ByteString(ByteString),
20 Integer(Integer),
22 List(Vec<Value>),
24 Dictionary(Dictionary),
26}
27
28impl Debug for Value {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 match self {
31 Self::ByteString(value) => f
32 .debug_tuple("ByteString")
33 .field(&String::from_utf8_lossy(value))
34 .finish(),
35 Self::Integer(value) => Debug::fmt(value, f),
36 Self::List(value) => {
37 f.write_str("List(")?;
38 Debug::fmt(value, f)?;
39 f.write_str(")")
40 }
41 Self::Dictionary(value) => {
42 f.write_str("Dictionary(")?;
43 Debug::fmt(value, f)?;
44 f.write_str(")")
45 }
46 }
47 }
48}
49
50impl Value {
51 pub const fn is_byte_string(&self) -> bool {
52 matches!(self, Self::ByteString(_))
53 }
54
55 pub const fn is_integer(&self) -> bool {
56 matches!(self, Self::Integer(_))
57 }
58
59 pub const fn is_list(&self) -> bool {
60 matches!(self, Self::Integer(_))
61 }
62
63 pub const fn is_dictionary(&self) -> bool {
64 matches!(self, Self::Dictionary(_))
65 }
66
67 pub const fn as_byte_string(&self) -> Option<&ByteString> {
68 match self {
69 Self::ByteString(byte_string) => Some(byte_string),
70 _ => None,
71 }
72 }
73
74 pub const fn as_integer(&self) -> Option<&Integer> {
75 match self {
76 Self::Integer(integer) => Some(integer),
77 _ => None,
78 }
79 }
80
81 pub const fn as_list(&self) -> Option<&Vec<Value>> {
82 match self {
83 Self::List(list) => Some(list),
84 _ => None,
85 }
86 }
87
88 pub const fn as_dictionary(&self) -> Option<&Dictionary> {
89 match self {
90 Self::Dictionary(dictionary) => Some(dictionary),
91 _ => None,
92 }
93 }
94}
95
96pub fn to_value<T>(value: T) -> Result<Value, Error>
97where
98 T: Serialize,
99{
100 value.serialize(ValueSerializer)
101}
102
103pub fn from_value<T>(value: Value) -> Result<T, Error>
104where
105 T: DeserializeOwned,
106{
107 T::deserialize(value)
108}
109
110#[cfg(test)]
111mod tests {
112 use super::{ByteString, Integer, Value};
113 use serde_test::{assert_tokens, Token};
114 use std::collections::BTreeMap;
115
116 #[test]
117 fn deserialize_and_serialize_dictionary() {
118 let mut map = BTreeMap::new();
119 map.insert(ByteString::from("a"), Value::Integer(Integer::from(10u64)));
120 map.insert(ByteString::from("c"), Value::Integer(Integer::from(10u64)));
121 map.insert(ByteString::from("d"), Value::Integer(Integer::from(10u64)));
122 map.insert(ByteString::from("b"), Value::Integer(Integer::from(10u64)));
123 map.insert(ByteString::from("e"), Value::Integer(Integer::from(10u64)));
124
125 let len = map.len();
126
127 assert_tokens(
128 &Value::Dictionary(map),
129 &[
130 Token::Map { len: Some(len) },
131 Token::Bytes(b"a"),
132 Token::U64(10),
133 Token::Bytes(b"b"),
134 Token::U64(10),
135 Token::Bytes(b"c"),
136 Token::U64(10),
137 Token::Bytes(b"d"),
138 Token::U64(10),
139 Token::Bytes(b"e"),
140 Token::U64(10),
141 Token::MapEnd,
142 ],
143 )
144 }
145}