value_trait/base.rs
1use std::io::{self, Write};
2
3use crate::{TryTypeError, ValueType, array::Array, object::Object};
4
5/// Type information on a value
6pub trait TypedValue {
7 /// Gets the type of the current value
8 #[must_use]
9 fn value_type(&self) -> ValueType;
10}
11
12/// Type checks for custom values on a value
13pub trait TypedCustomValue {
14 #[cfg(feature = "custom-types")]
15 /// returns if a type is a custom type
16 fn is_custom(&self) -> bool {
17 false
18 }
19}
20
21/// Access to scalar value types
22pub trait ValueAsScalar {
23 /// Tries to represent the value as a 'null';
24 #[must_use]
25 fn as_null(&self) -> Option<()>;
26
27 /// Tries to represent the value as a bool
28 #[must_use]
29 fn as_bool(&self) -> Option<bool>;
30
31 /// Tries to represent the value as an i128
32 #[inline]
33 #[must_use]
34 fn as_i128(&self) -> Option<i128> {
35 self.as_i64().map(Into::into)
36 }
37
38 /// Tries to represent the value as an i64
39 #[must_use]
40 fn as_i64(&self) -> Option<i64>;
41
42 /// Tries to represent the value as an i32
43 #[inline]
44 #[must_use]
45 fn as_i32(&self) -> Option<i32> {
46 self.as_i64().and_then(|u| u.try_into().ok())
47 }
48
49 /// Tries to represent the value as an i16
50 #[inline]
51 #[must_use]
52 fn as_i16(&self) -> Option<i16> {
53 self.as_i64().and_then(|u| u.try_into().ok())
54 }
55
56 /// Tries to represent the value as an i8
57 #[inline]
58 #[must_use]
59 fn as_i8(&self) -> Option<i8> {
60 self.as_i64().and_then(|u| u.try_into().ok())
61 }
62
63 /// Tries to represent the value as an u128
64 #[inline]
65 #[must_use]
66 fn as_u128(&self) -> Option<u128> {
67 self.as_u64().map(Into::into)
68 }
69
70 /// Tries to represent the value as an u64
71 #[must_use]
72 fn as_u64(&self) -> Option<u64>;
73
74 /// Tries to represent the value as an usize
75 #[inline]
76 #[must_use]
77 fn as_usize(&self) -> Option<usize> {
78 self.as_u64().and_then(|u| u.try_into().ok())
79 }
80
81 /// Tries to represent the value as an u32
82 #[inline]
83 #[must_use]
84 fn as_u32(&self) -> Option<u32> {
85 self.as_u64().and_then(|u| u.try_into().ok())
86 }
87 /// Tries to represent the value as an u16
88 #[inline]
89 #[must_use]
90 fn as_u16(&self) -> Option<u16> {
91 self.as_u64().and_then(|u| u.try_into().ok())
92 }
93
94 /// Tries to represent the value as an u8
95 #[inline]
96 #[must_use]
97 fn as_u8(&self) -> Option<u8> {
98 self.as_u64().and_then(|u| u.try_into().ok())
99 }
100
101 /// Tries to represent the value as a f64
102 #[must_use]
103 fn as_f64(&self) -> Option<f64>;
104
105 /// Tries to represent the value as a f32
106 #[inline]
107 #[must_use]
108 fn as_f32(&self) -> Option<f32> {
109 self.as_f64().and_then(|u| {
110 if u <= f64::from(f32::MAX) && u >= f64::from(f32::MIN) {
111 // Since we check above
112 #[allow(clippy::cast_possible_truncation)]
113 Some(u as f32)
114 } else {
115 None
116 }
117 })
118 }
119
120 /// Casts the current value to a f64 if possible, this will turn integer
121 /// values into floats.
122 #[must_use]
123 #[inline]
124 #[allow(clippy::cast_precision_loss, clippy::option_if_let_else)]
125 fn cast_f64(&self) -> Option<f64> {
126 if let Some(f) = self.as_f64() {
127 Some(f)
128 } else if let Some(u) = self.as_u128() {
129 Some(u as f64)
130 } else {
131 self.as_i128().map(|i| i as f64)
132 }
133 }
134
135 /// Tries to represent the value as a &str
136 #[must_use]
137 fn as_str(&self) -> Option<&str>;
138
139 /// Tries to represent the value as a Char
140 #[inline]
141 #[must_use]
142 fn as_char(&self) -> Option<char> {
143 self.as_str().and_then(|s| s.chars().next())
144 }
145}
146
147/// Trait to allow accessing data inside a Value
148pub trait ValueAsArray {
149 /// The array structure
150 type Array: Array;
151
152 /// Tries to represent the value as an array and returns a reference to it
153 #[must_use]
154 fn as_array(&self) -> Option<&Self::Array>;
155}
156
157/// Trait to allow Value as an object
158pub trait ValueAsObject {
159 /// The object structure
160 type Object: Object;
161
162 /// Tries to represent the value as an object and returns a reference to it
163 #[must_use]
164 fn as_object(&self) -> Option<&Self::Object>;
165}
166
167/// Mutatability for Array values
168pub trait ValueAsMutArray {
169 /// The type for Arrays
170 type Array;
171 /// Tries to represent the value as an array and returns a mutable reference to it
172 fn as_array_mut(&mut self) -> Option<&mut Self::Array>;
173}
174
175/// `try_as_array_mut` access to array value types
176pub trait ValueTryAsArrayMut {
177 /// The array structure
178 type Array: Array;
179
180 /// Tries to represent the value as an array and returns a mutable reference to it
181 /// # Errors
182 /// if the requested type doesn't match the actual type
183 fn try_as_array_mut(&mut self) -> Result<&mut Self::Array, TryTypeError>;
184}
185
186/// Mutatability for Object values
187pub trait ValueAsMutObject {
188 /// The type for Objects
189 type Object;
190 /// Tries to represent the value as an object and returns a mutable reference to it
191 fn as_object_mut(&mut self) -> Option<&mut Self::Object>;
192}
193/// Mutatability for Object values
194pub trait ValueTryAsMutObject {
195 /// The type for Objects
196 type Object;
197 /// Tries to represent the value as an object and returns a mutable reference to it
198 /// # Errors
199 /// if the requested type doesn't match the actual type
200 fn try_as_object_mut(&mut self) -> Result<&mut Self::Object, TryTypeError>;
201}
202
203/// A trait that specifies how to turn the Value `into` it's sub types
204pub trait ValueIntoString {
205 /// The type for Strings
206 type String;
207
208 /// Tries to turn the value into it's string representation
209 #[must_use]
210 fn into_string(self) -> Option<Self::String>;
211}
212
213/// A trait that specifies how to turn the Value `into` it's sub types
214pub trait ValueIntoArray {
215 /// The type for Arrays
216 type Array;
217
218 /// Tries to turn the value into it's array representation
219 #[must_use]
220 fn into_array(self) -> Option<Self::Array>;
221}
222/// A trait that specifies how to turn the Value `into` it's sub types
223pub trait ValueIntoObject {
224 /// The type for Objects
225 type Object;
226
227 /// Tries to turn the value into it's object representation
228 #[must_use]
229 fn into_object(self) -> Option<Self::Object>;
230}
231
232/// A Value that can be serialized and written
233pub trait Writable {
234 /// Encodes the value into it's JSON representation as a string
235 #[must_use]
236 fn encode(&self) -> String;
237
238 /// Encodes the value into it's JSON representation as a string (pretty printed)
239 #[must_use]
240 fn encode_pp(&self) -> String;
241
242 /// Encodes the value into it's JSON representation into a Writer
243 ///
244 /// # Errors
245 ///
246 /// Will return `Err` if an IO error is encountered
247 fn write<'writer, W>(&self, w: &mut W) -> io::Result<()>
248 where
249 W: 'writer + Write;
250
251 /// Encodes the value into it's JSON representation into a Writer, pretty printed
252 ///
253 /// # Errors
254 ///
255 /// Will return `Err` if an IO error is encountered.
256 fn write_pp<'writer, W>(&self, w: &mut W) -> io::Result<()>
257 where
258 W: 'writer + Write;
259}