deserr/
value.rs

1use std::{
2    convert::Infallible,
3    fmt::{Debug, Display},
4};
5
6/// A location within a [`Value`].
7///
8/// Conceptually, it is a list of choices that one has to make to go to a certain place within
9/// the value. In practice, it is used to locate the origin of a deserialization error.
10///
11/// ## Example
12/// ```
13/// use deserr::ValuePointerRef;
14///
15/// let pointer = ValuePointerRef::Origin;
16/// let pointer = pointer.push_key("a");
17/// let pointer = pointer.push_index(2);
18/// // now `pointer` points to "a".2
19/// ```
20///
21/// A `ValuePointerRef` is an immutable data structure, so it is cheap to extend and to copy.
22/// However, if you want to store it inside an owned type, you may want to convert it to a
23/// [`ValuePointer`] instead using [`self.to_owned()`](ValuePointerRef::to_owned).
24#[derive(Clone, Copy)]
25pub enum ValuePointerRef<'a> {
26    Origin,
27    Key {
28        key: &'a str,
29        prev: &'a ValuePointerRef<'a>,
30    },
31    Index {
32        index: usize,
33        prev: &'a ValuePointerRef<'a>,
34    },
35}
36
37impl Default for ValuePointerRef<'_> {
38    fn default() -> Self {
39        Self::Origin
40    }
41}
42
43impl<'a> ValuePointerRef<'a> {
44    /// Extend `self` such that it points to the next subvalue at the given `key`.
45    #[must_use]
46    pub fn push_key(&'a self, key: &'a str) -> Self {
47        Self::Key { key, prev: self }
48    }
49
50    #[must_use]
51    /// Extend `self` such that it points to the next subvalue at the given index.
52    pub fn push_index(&'a self, index: usize) -> Self {
53        Self::Index { index, prev: self }
54    }
55
56    /// Return true if the pointer is at the origin.
57    pub fn is_origin(&self) -> bool {
58        matches!(self, ValuePointerRef::Origin)
59    }
60
61    /// Return the last field encountered if there is one.
62    pub fn last_field(&self) -> Option<&str> {
63        match self {
64            ValuePointerRef::Origin => None,
65            ValuePointerRef::Key { key, .. } => Some(key),
66            ValuePointerRef::Index { prev, .. } => prev.last_field(),
67        }
68    }
69
70    /// Return the first field encountered if there is one.
71    /// Eg;
72    /// "toto.tata[42].lol" -> "toto"
73    /// "toto" -> "toto"
74    /// "[1][2][3]" -> None
75    /// "" -> None
76    pub fn first_field(&self) -> Option<&str> {
77        match self {
78            ValuePointerRef::Origin => None,
79            ValuePointerRef::Key { key, prev } => prev.first_field().or(Some(key)),
80            ValuePointerRef::Index { prev, .. } => prev.first_field(),
81        }
82    }
83
84    /// Convert `self` to its owned version
85    pub fn to_owned(&self) -> ValuePointer {
86        let mut cur = self;
87        let mut components = vec![];
88        loop {
89            match cur {
90                ValuePointerRef::Origin => break,
91                ValuePointerRef::Key { key, prev } => {
92                    components.push(ValuePointerComponent::Key(key.to_string()));
93                    cur = prev;
94                }
95                ValuePointerRef::Index { index, prev } => {
96                    components.push(ValuePointerComponent::Index(*index));
97                    cur = prev;
98                }
99            }
100        }
101        let components = components.into_iter().rev().collect();
102        ValuePointer { path: components }
103    }
104}
105
106/// Part of a [`ValuePointer`]
107#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
108pub enum ValuePointerComponent {
109    Key(String),
110    Index(usize),
111}
112
113/// The owned version of a [`ValuePointerRef`].
114#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
115pub struct ValuePointer {
116    pub path: Vec<ValuePointerComponent>,
117}
118
119/// Equivalent to [`Value`] but without the associated data.
120#[derive(Clone, Copy, PartialEq, Eq)]
121pub enum ValueKind {
122    Null,
123    Boolean,
124    Integer,
125    NegativeInteger,
126    Float,
127    String,
128    Sequence,
129    Map,
130}
131
132impl Display for ValueKind {
133    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134        match self {
135            ValueKind::Null => write!(f, "Null"),
136            ValueKind::Boolean => write!(f, "Boolean"),
137            ValueKind::Integer => write!(f, "Integer"),
138            ValueKind::NegativeInteger => write!(f, "NegativeInteger"),
139            ValueKind::Float => write!(f, "Float"),
140            ValueKind::String => write!(f, "String"),
141            ValueKind::Sequence => write!(f, "Sequence"),
142            ValueKind::Map => write!(f, "Map"),
143        }
144    }
145}
146
147impl Debug for ValueKind {
148    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149        Display::fmt(self, f)
150    }
151}
152
153/// `Value<V>` is a view into the parsed serialization data (of type `V`) that
154/// is readable by Deserr.
155///
156/// It is an enum with a variant for each possible value kind. The content of the variants
157/// is either a simple value, such as `bool` or `String`, or an abstract [`Sequence`] or
158/// [`Map`], which are views into the rest of the serialized data.
159#[derive(Debug)]
160pub enum Value<V: IntoValue> {
161    Null,
162    Boolean(bool),
163    Integer(u64),
164    NegativeInteger(i64),
165    Float(f64),
166    String(String),
167    Sequence(V::Sequence),
168    Map(V::Map),
169}
170
171impl<V: IntoValue> Value<V> {
172    pub fn kind(&self) -> ValueKind {
173        match self {
174            Value::Null => ValueKind::Null,
175            Value::Boolean(_) => ValueKind::Boolean,
176            Value::Integer(_) => ValueKind::Integer,
177            Value::NegativeInteger(_) => ValueKind::NegativeInteger,
178            Value::Float(_) => ValueKind::Float,
179            Value::String(_) => ValueKind::String,
180            Value::Sequence(_) => ValueKind::Sequence,
181            Value::Map(_) => ValueKind::Map,
182        }
183    }
184}
185
186/// A trait for a value that can be deserialized via [`Deserr`].
187pub trait IntoValue: Sized {
188    type Sequence: Sequence<Value = Self>;
189    type Map: Map<Value = Self>;
190
191    fn kind(&self) -> ValueKind;
192    fn into_value(self) -> Value<Self>;
193}
194
195/// A sequence of values conforming to [`IntoValue`].
196pub trait Sequence {
197    type Value: IntoValue;
198    type Iter: Iterator<Item = Self::Value>;
199
200    fn len(&self) -> usize;
201    fn into_iter(self) -> Self::Iter;
202
203    fn is_empty(&self) -> bool {
204        self.len() == 0
205    }
206}
207
208/// A keyed map of values conforming to [`IntoValue`].
209pub trait Map {
210    type Value: IntoValue;
211    type Iter: Iterator<Item = (String, Self::Value)>;
212
213    fn len(&self) -> usize;
214    fn remove(&mut self, key: &str) -> Option<Self::Value>;
215    fn into_iter(self) -> Self::Iter;
216
217    fn is_empty(&self) -> bool {
218        self.len() == 0
219    }
220}
221
222impl IntoValue for Infallible {
223    type Sequence = Self;
224    type Map = Self;
225
226    fn kind(&self) -> ValueKind {
227        unreachable!()
228    }
229
230    fn into_value(self) -> Value<Self> {
231        unreachable!()
232    }
233}
234
235impl Sequence for Infallible {
236    type Value = Self;
237    type Iter = std::iter::Empty<Infallible>;
238
239    fn len(&self) -> usize {
240        unreachable!()
241    }
242
243    fn into_iter(self) -> Self::Iter {
244        unreachable!()
245    }
246}
247
248impl Map for Infallible {
249    type Value = Self;
250    type Iter = std::iter::Empty<(String, Infallible)>;
251
252    fn len(&self) -> usize {
253        unreachable!()
254    }
255
256    fn remove(&mut self, _key: &str) -> Option<Self::Value> {
257        unreachable!()
258    }
259
260    fn into_iter(self) -> Self::Iter {
261        unreachable!()
262    }
263}