ssi_vc/syntax/
non_empty_object.rs

1use json_syntax::{
2    object::{
3        Duplicate, Entry, Equivalent, IterMut, Key, RemovedByInsertFront, RemovedByInsertion,
4        RemovedEntries, ValuesMut,
5    },
6    Object, Value,
7};
8use serde::Serialize;
9use std::{borrow::Borrow, hash::Hash, ops::Deref};
10
11/// Non-empty JSON object.
12#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
13#[serde(transparent)]
14pub struct NonEmptyObject(Object);
15
16impl NonEmptyObject {
17    pub fn try_from_object(object: Object) -> Result<Self, EmptyObject> {
18        if object.is_empty() {
19            Err(EmptyObject)
20        } else {
21            Ok(Self(object))
22        }
23    }
24
25    pub fn as_object(&self) -> &Object {
26        &self.0
27    }
28
29    pub fn into_object(self) -> Object {
30        self.0
31    }
32
33    pub fn iter_mut(&mut self) -> IterMut {
34        self.0.iter_mut()
35    }
36
37    /// Returns an iterator over the values matching the given key.
38    ///
39    /// Runs in `O(1)` (average).
40    pub fn get_mut<Q>(&mut self, key: &Q) -> ValuesMut
41    where
42        Q: ?Sized + Hash + Equivalent<Key>,
43    {
44        self.0.get_mut(key)
45    }
46
47    /// Returns the unique entry value matching the given key.
48    ///
49    /// Returns an error if multiple entries match the key.
50    ///
51    /// Runs in `O(1)` (average).
52    pub fn get_unique_mut<Q>(&mut self, key: &Q) -> Result<Option<&mut Value>, Duplicate<&Entry>>
53    where
54        Q: ?Sized + Hash + Equivalent<Key>,
55    {
56        self.0.get_unique_mut(key)
57    }
58
59    /// Returns the (first) value associated to `key`, or insert a `key`-`value`
60    /// entry where `value` is returned by the given function `f`.
61    pub fn get_or_insert_with<Q>(&mut self, key: &Q, f: impl FnOnce() -> Value) -> &Value
62    where
63        Q: ?Sized + Hash + Equivalent<Key> + ToOwned,
64        Q::Owned: Into<Key>,
65    {
66        self.0.get_or_insert_with(key, f)
67    }
68
69    /// Returns a mutable reference to the (first) value associated to `key`, or
70    /// insert a `key`-`value` entry where `value` is returned by the given
71    /// function `f`.
72    pub fn get_mut_or_insert_with<Q>(&mut self, key: &Q, f: impl FnOnce() -> Value) -> &mut Value
73    where
74        Q: ?Sized + Hash + Equivalent<Key> + ToOwned,
75        Q::Owned: Into<Key>,
76    {
77        self.0.get_mut_or_insert_with(key, f)
78    }
79
80    /// Push the given key-value pair to the end of the object.
81    ///
82    /// Returns `true` if the key was not already present in the object,
83    /// and `false` otherwise.
84    /// Any previous entry matching the key is **not** overridden: duplicates
85    /// are preserved, in order.
86    ///
87    /// Runs in `O(1)`.
88    pub fn push(&mut self, key: Key, value: Value) -> bool {
89        self.0.push(key, value)
90    }
91
92    pub fn push_entry(&mut self, entry: Entry) -> bool {
93        self.0.push_entry(entry)
94    }
95
96    /// Push the given key-value pair to the top of the object.
97    ///
98    /// Returns `true` if the key was not already present in the object,
99    /// and `false` otherwise.
100    /// Any previous entry matching the key is **not** overridden: duplicates
101    /// are preserved, in order.
102    ///
103    /// Runs in `O(n)`.
104    pub fn push_front(&mut self, key: Key, value: Value) -> bool {
105        self.0.push_front(key, value)
106    }
107
108    pub fn push_entry_front(&mut self, entry: Entry) -> bool {
109        self.0.push_entry_front(entry)
110    }
111
112    /// Inserts the given key-value pair.
113    ///
114    /// If one or more entries are already matching the given key,
115    /// all of them are removed and returned in the resulting iterator.
116    /// Otherwise, `None` is returned.
117    pub fn insert(&mut self, key: Key, value: Value) -> Option<RemovedByInsertion> {
118        self.0.insert(key, value)
119    }
120
121    /// Inserts the given key-value pair on top of the object.
122    ///
123    /// If one or more entries are already matching the given key,
124    /// all of them are removed and returned in the resulting iterator.
125    pub fn insert_front(&mut self, key: Key, value: Value) -> RemovedByInsertFront {
126        self.0.insert_front(key, value)
127    }
128
129    /// Sort the entries by key name.
130    ///
131    /// Entries with the same key are sorted by value.
132    pub fn sort(&mut self) {
133        self.0.sort()
134    }
135
136    /// Tries to remove the entry at the given index.
137    ///
138    /// Returns an error if this would leave the object empty.
139    pub fn try_remove_at(&mut self, index: usize) -> Result<Option<Entry>, EmptyObject> {
140        if index == 0 && self.0.len() == 1 {
141            Err(EmptyObject)
142        } else {
143            Ok(self.0.remove_at(index))
144        }
145    }
146
147    /// Tries to remove all entries associated to the given key.
148    ///
149    /// Returns an error if this would leave the object empty.
150    ///
151    /// Runs in `O(n)` time (average).
152    pub fn try_remove<'q, Q>(
153        &mut self,
154        key: &'q Q,
155    ) -> Result<RemovedEntries<'_, 'q, Q>, EmptyObject>
156    where
157        Q: ?Sized + Hash + Equivalent<Key>,
158    {
159        if self.iter().all(|e| key.equivalent(&e.key)) {
160            Err(EmptyObject)
161        } else {
162            Ok(self.0.remove(key))
163        }
164    }
165
166    /// Tries to remove the unique entry associated to the given key.
167    ///
168    /// Returns an error if multiple entries match the key, or if the object
169    /// would be left empty.
170    ///
171    /// Runs in `O(n)` time (average).
172    pub fn try_remove_unique<Q>(&mut self, key: &Q) -> Result<Option<Entry>, RemoveUniqueError>
173    where
174        Q: ?Sized + Hash + Equivalent<Key>,
175    {
176        if self.iter().all(|e| key.equivalent(&e.key)) {
177            Err(RemoveUniqueError::EmptyObject)
178        } else {
179            self.0.remove_unique(key).map_err(Into::into)
180        }
181    }
182}
183
184#[derive(Debug, thiserror::Error)]
185#[error("empty object")]
186pub struct EmptyObject;
187
188#[derive(Debug, thiserror::Error)]
189pub enum RemoveUniqueError {
190    #[error(transparent)]
191    DuplicateEntry(Box<Duplicate<Entry>>),
192
193    #[error("empty object")]
194    EmptyObject,
195}
196
197impl From<Duplicate<Entry>> for RemoveUniqueError {
198    fn from(value: Duplicate<Entry>) -> Self {
199        Self::DuplicateEntry(Box::new(value))
200    }
201}
202
203impl Deref for NonEmptyObject {
204    type Target = Object;
205
206    fn deref(&self) -> &Self::Target {
207        &self.0
208    }
209}
210
211impl Borrow<Object> for NonEmptyObject {
212    fn borrow(&self) -> &Object {
213        self.as_object()
214    }
215}
216
217impl AsRef<Object> for NonEmptyObject {
218    fn as_ref(&self) -> &Object {
219        self.as_object()
220    }
221}
222
223impl From<NonEmptyObject> for Object {
224    fn from(value: NonEmptyObject) -> Self {
225        value.into_object()
226    }
227}
228
229impl TryFrom<Object> for NonEmptyObject {
230    type Error = EmptyObject;
231
232    fn try_from(value: Object) -> Result<Self, Self::Error> {
233        Self::try_from_object(value)
234    }
235}
236
237impl<'de> serde::Deserialize<'de> for NonEmptyObject {
238    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
239    where
240        D: serde::Deserializer<'de>,
241    {
242        Object::deserialize(deserializer)?
243            .try_into()
244            .map_err(serde::de::Error::custom)
245    }
246}