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 one(self) -> Result<(Key, E), Error> {
76 self.require_one()?;
77 Ok(self.0.into_iter().next().unwrap())
78 }
79
80 pub fn one_opt(self) -> Result<Option<(Key, E)>, Error> {
82 match self.count() {
83 0 => Ok(None),
84 1 => Ok(Some(self.0.into_iter().next().unwrap())),
85 n => Err(ResponseError::NotUnique {
86 entity: E::PATH,
87 count: n,
88 }
89 .into()),
90 }
91 }
92
93 #[must_use]
99 pub fn key(&self) -> Option<Key> {
100 self.0.first().map(|(k, _)| *k)
101 }
102
103 #[must_use]
105 pub fn keys(&self) -> Vec<Key> {
106 self.0.iter().map(|(k, _)| *k).collect()
107 }
108
109 pub fn one_key(self) -> Result<Key, Error> {
111 self.one().map(|(k, _)| k)
112 }
113
114 pub fn one_opt_key(self) -> Result<Option<Key>, Error> {
116 Ok(self.one_opt()?.map(|(k, _)| k))
117 }
118
119 #[must_use]
120 pub fn contains_key(&self, key: &Key) -> bool {
121 self.0.iter().any(|(k, _)| k == key)
122 }
123
124 #[must_use]
130 pub fn entity(self) -> Option<E> {
131 self.0.into_iter().next().map(|(_, e)| e)
132 }
133
134 #[must_use]
136 pub fn entities(self) -> Vec<E> {
137 self.0.into_iter().map(|(_, e)| e).collect()
138 }
139
140 pub fn one_entity(self) -> Result<E, Error> {
142 self.one().map(|(_, e)| e)
143 }
144
145 pub fn one_opt_entity(self) -> Result<Option<E>, Error> {
147 Ok(self.one_opt()?.map(|(_, e)| e))
148 }
149
150 #[must_use]
156 pub fn pk(&self) -> Option<E::PrimaryKey> {
157 self.0.first().map(|(_, e)| e.primary_key())
158 }
159
160 #[must_use]
162 pub fn pks(&self) -> Vec<E::PrimaryKey> {
163 self.0.iter().map(|(_, e)| e.primary_key()).collect()
164 }
165
166 pub fn one_pk(self) -> Result<E::PrimaryKey, Error> {
168 self.one_entity().map(|e| e.primary_key())
169 }
170
171 pub fn one_opt_pk(self) -> Result<Option<E::PrimaryKey>, Error> {
173 Ok(self.one_opt_entity()?.map(|e| e.primary_key()))
174 }
175
176 #[must_use]
182 pub fn view(self) -> Option<E::ViewType> {
183 self.entity().map(|e| e.to_view())
184 }
185
186 pub fn one_view(self) -> Result<E::ViewType, Error> {
188 self.one_entity().map(|e| e.to_view())
189 }
190
191 pub fn one_opt_view(self) -> Result<Option<E::ViewType>, Error> {
193 Ok(self.one_opt_entity()?.map(|e| e.to_view()))
194 }
195
196 #[must_use]
198 pub fn views(self) -> Vec<E::ViewType> {
199 self.entities().into_iter().map(|e| e.to_view()).collect()
200 }
201
202 #[must_use]
211 pub fn first(self) -> Option<(Key, E)> {
212 self.0.into_iter().next()
213 }
214
215 #[must_use]
220 pub fn first_entity(self) -> Option<E> {
221 self.first().map(|(_, e)| e)
222 }
223
224 #[must_use]
228 pub fn first_pk(self) -> Option<E::PrimaryKey> {
229 self.first_entity().map(|e| e.primary_key())
230 }
231}
232
233impl<E: EntityKind> IntoIterator for Response<E> {
234 type Item = (Key, E);
235 type IntoIter = std::vec::IntoIter<Self::Item>;
236
237 fn into_iter(self) -> Self::IntoIter {
238 self.0.into_iter()
239 }
240}