ssi_vc/syntax/
non_empty_object.rs1use 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#[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 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 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 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 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 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 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 pub fn insert(&mut self, key: Key, value: Value) -> Option<RemovedByInsertion> {
118 self.0.insert(key, value)
119 }
120
121 pub fn insert_front(&mut self, key: Key, value: Value) -> RemovedByInsertFront {
126 self.0.insert_front(key, value)
127 }
128
129 pub fn sort(&mut self) {
133 self.0.sort()
134 }
135
136 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 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 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}