icydb_core/db/response/
mod.rs1mod ext;
2
3pub use ext::*;
4
5use crate::{Error, Key, ThisError, db::DbError, traits::EntityKind};
6
7#[derive(Debug, ThisError)]
13pub enum ResponseError {
14 #[error("expected exactly one row, found 0 (entity {entity})")]
15 NotFound { entity: &'static str },
16
17 #[error("expected exactly one row, found {count} (entity {entity})")]
18 NotUnique { entity: &'static str, count: u32 },
19}
20
21impl From<ResponseError> for Error {
22 fn from(err: ResponseError) -> Self {
23 DbError::from(err).into()
24 }
25}
26
27#[derive(Debug)]
33pub struct Response<E: EntityKind>(pub Vec<(Key, E)>);
34
35impl<E: EntityKind> Response<E> {
36 #[must_use]
42 #[allow(clippy::cast_possible_truncation)]
43 pub const fn count(&self) -> u32 {
44 self.0.len() as u32
45 }
46
47 #[must_use]
49 pub const fn is_empty(&self) -> bool {
50 self.0.is_empty()
51 }
52
53 pub fn require_one(&self) -> Result<(), Error> {
59 match self.count() {
60 1 => Ok(()),
61 0 => Err(ResponseError::NotFound { entity: E::PATH }.into()),
62 n => Err(ResponseError::NotUnique {
63 entity: E::PATH,
64 count: n,
65 }
66 .into()),
67 }
68 }
69
70 pub fn require_some(&self) -> Result<(), Error> {
72 match self.count() {
73 0 => Err(ResponseError::NotFound { entity: E::PATH }.into()),
74 _ => Ok(()),
75 }
76 }
77
78 pub fn require_len(&self, expected: u32) -> Result<(), Error> {
80 let actual = self.count();
81 if actual == expected {
82 Ok(())
83 } else if actual == 0 {
84 Err(ResponseError::NotFound { entity: E::PATH }.into())
85 } else {
86 Err(ResponseError::NotUnique {
87 entity: E::PATH,
88 count: actual,
89 }
90 .into())
91 }
92 }
93
94 pub fn one(self) -> Result<(Key, E), Error> {
100 self.require_one()?;
101 Ok(self.0.into_iter().next().unwrap())
102 }
103
104 pub fn one_opt(self) -> Result<Option<(Key, E)>, Error> {
106 match self.count() {
107 0 => Ok(None),
108 1 => Ok(Some(self.0.into_iter().next().unwrap())),
109 n => Err(ResponseError::NotUnique {
110 entity: E::PATH,
111 count: n,
112 }
113 .into()),
114 }
115 }
116
117 #[must_use]
123 pub fn key(&self) -> Option<Key> {
124 self.0.first().map(|(k, _)| *k)
125 }
126
127 #[must_use]
129 pub fn keys(&self) -> Vec<Key> {
130 self.0.iter().map(|(k, _)| *k).collect()
131 }
132
133 pub fn one_key(self) -> Result<Key, Error> {
135 self.one().map(|(k, _)| k)
136 }
137
138 pub fn one_opt_key(self) -> Result<Option<Key>, Error> {
140 Ok(self.one_opt()?.map(|(k, _)| k))
141 }
142
143 #[must_use]
144 pub fn contains_key(&self, key: &Key) -> bool {
145 self.0.iter().any(|(k, _)| k == key)
146 }
147
148 #[must_use]
154 pub fn entity(self) -> Option<E> {
155 self.0.into_iter().next().map(|(_, e)| e)
156 }
157
158 #[must_use]
160 pub fn entities(self) -> Vec<E> {
161 self.0.into_iter().map(|(_, e)| e).collect()
162 }
163
164 pub fn one_entity(self) -> Result<E, Error> {
166 self.one().map(|(_, e)| e)
167 }
168
169 pub fn one_opt_entity(self) -> Result<Option<E>, Error> {
171 Ok(self.one_opt()?.map(|(_, e)| e))
172 }
173
174 #[must_use]
180 pub fn pk(&self) -> Option<E::PrimaryKey> {
181 self.0.first().map(|(_, e)| e.primary_key())
182 }
183
184 #[must_use]
186 pub fn pks(&self) -> Vec<E::PrimaryKey> {
187 self.0.iter().map(|(_, e)| e.primary_key()).collect()
188 }
189
190 pub fn one_pk(self) -> Result<E::PrimaryKey, Error> {
192 self.one_entity().map(|e| e.primary_key())
193 }
194
195 pub fn one_opt_pk(self) -> Result<Option<E::PrimaryKey>, Error> {
197 Ok(self.one_opt_entity()?.map(|e| e.primary_key()))
198 }
199
200 #[must_use]
206 pub fn view(self) -> Option<E::ViewType> {
207 self.entity().map(|e| e.to_view())
208 }
209
210 pub fn one_view(self) -> Result<E::ViewType, Error> {
212 self.one_entity().map(|e| e.to_view())
213 }
214
215 pub fn one_opt_view(self) -> Result<Option<E::ViewType>, Error> {
217 Ok(self.one_opt_entity()?.map(|e| e.to_view()))
218 }
219
220 #[must_use]
222 pub fn views(self) -> Vec<E::ViewType> {
223 self.entities().into_iter().map(|e| e.to_view()).collect()
224 }
225
226 #[must_use]
235 pub fn first(self) -> Option<(Key, E)> {
236 self.0.into_iter().next()
237 }
238
239 #[must_use]
244 pub fn first_entity(self) -> Option<E> {
245 self.first().map(|(_, e)| e)
246 }
247
248 #[must_use]
252 pub fn first_pk(self) -> Option<E::PrimaryKey> {
253 self.first_entity().map(|e| e.primary_key())
254 }
255}
256
257impl<E: EntityKind> IntoIterator for Response<E> {
258 type Item = (Key, E);
259 type IntoIter = std::vec::IntoIter<Self::Item>;
260
261 fn into_iter(self) -> Self::IntoIter {
262 self.0.into_iter()
263 }
264}