icydb_core/db/response/
mod.rs1use crate::{Error, Key, ThisError, db::DbError, traits::EntityKind};
2
3#[derive(Debug, ThisError)]
9pub enum ResponseError {
10 #[error("expected exactly one row, found 0 (entity {entity})")]
11 NotFound { entity: &'static str },
12
13 #[error("expected exactly one row, found {count} (entity {entity})")]
14 NotUnique { entity: &'static str, count: u32 },
15}
16
17impl From<ResponseError> for Error {
18 fn from(err: ResponseError) -> Self {
19 DbError::from(err).into()
20 }
21}
22
23#[derive(Debug)]
29pub struct Response<E: EntityKind>(pub Vec<(Key, E)>);
30
31impl<E: EntityKind> Response<E> {
32 #[must_use]
37 #[allow(clippy::cast_possible_truncation)]
39 pub const fn count(&self) -> u32 {
40 self.0.len() as u32
41 }
42
43 #[must_use]
44 pub const fn is_empty(&self) -> bool {
46 self.0.is_empty()
47 }
48
49 pub fn one(self) -> Result<(Key, E), Error> {
55 let count = self.count();
56
57 match count {
58 0 => Err(ResponseError::NotFound { entity: E::PATH }.into()),
59 1 => Ok(self.0.into_iter().next().unwrap()),
60 _ => Err(ResponseError::NotUnique {
61 entity: E::PATH,
62 count,
63 }
64 .into()),
65 }
66 }
67
68 pub fn one_entity(self) -> Result<E, Error> {
70 self.one().map(|(_, e)| e)
71 }
72
73 pub fn one_opt(self) -> Result<Option<(Key, E)>, Error> {
75 let count = self.count();
76
77 match count {
78 0 => Ok(None),
79 1 => Ok(Some(self.0.into_iter().next().unwrap())),
80 _ => Err(ResponseError::NotUnique {
81 entity: E::PATH,
82 count,
83 }
84 .into()),
85 }
86 }
87
88 pub fn one_opt_entity(self) -> Result<Option<E>, Error> {
90 Ok(self.one_opt()?.map(|(_, e)| e))
91 }
92
93 #[must_use]
98 pub fn key(&self) -> Option<Key> {
100 self.0.first().map(|(key, _)| *key)
101 }
102
103 #[must_use]
104 pub fn keys(&self) -> Vec<Key> {
106 self.0.iter().map(|(key, _)| *key).collect()
107 }
108
109 pub fn keys_iter(self) -> impl Iterator<Item = Key> {
111 self.0.into_iter().map(|(key, _)| key)
112 }
113
114 pub fn one_key(self) -> Result<Key, Error> {
116 self.one().map(|(key, _)| key)
117 }
118
119 pub fn one_opt_key(self) -> Result<Option<Key>, Error> {
121 Ok(self.one_opt()?.map(|(key, _)| key))
122 }
123
124 #[must_use]
125 pub fn contains_key(&self, key: &Key) -> bool {
126 self.0.iter().any(|(k, _)| k == key)
127 }
128
129 #[must_use]
134 pub fn pk(&self) -> Option<E::PrimaryKey> {
136 self.0.first().map(|(_, e)| e.primary_key())
137 }
138
139 #[must_use]
140 pub fn pks(&self) -> Vec<E::PrimaryKey> {
142 self.0.iter().map(|(_, e)| e.primary_key()).collect()
143 }
144
145 pub fn pks_iter(self) -> impl Iterator<Item = E::PrimaryKey> {
147 self.0.into_iter().map(|(_, e)| e.primary_key())
148 }
149
150 pub fn one_pk(self) -> Result<E::PrimaryKey, Error> {
151 self.one_entity().map(|e| e.primary_key())
152 }
153
154 pub fn one_opt_pk(self) -> Result<Option<E::PrimaryKey>, Error> {
155 Ok(self.one_opt_entity()?.map(|e| e.primary_key()))
156 }
157
158 #[must_use]
163 pub fn entity(self) -> Option<E> {
165 self.0.into_iter().next().map(|(_, e)| e)
166 }
167
168 #[must_use]
169 pub fn entities(self) -> Vec<E> {
171 self.0.into_iter().map(|(_, e)| e).collect()
172 }
173
174 pub fn entities_iter(self) -> impl Iterator<Item = E> {
176 self.0.into_iter().map(|(_, e)| e)
177 }
178
179 #[must_use]
184 pub fn view(self) -> Option<E::ViewType> {
186 self.entity().map(|e| e.to_view())
187 }
188
189 pub fn one_view(self) -> Result<E::ViewType, Error> {
191 self.one_entity().map(|e| e.to_view())
192 }
193
194 pub fn one_opt_view(self) -> Result<Option<E::ViewType>, Error> {
196 Ok(self.one_opt_entity()?.map(|e| e.to_view()))
197 }
198
199 #[must_use]
200 pub fn views(self) -> Vec<E::ViewType> {
202 self.entities().into_iter().map(|e| e.to_view()).collect()
203 }
204
205 pub fn views_iter(self) -> impl Iterator<Item = E::ViewType> {
207 self.entities().into_iter().map(|e| e.to_view())
208 }
209}
210
211impl<E: EntityKind> IntoIterator for Response<E> {
212 type Item = (Key, E);
213 type IntoIter = std::vec::IntoIter<Self::Item>;
214
215 fn into_iter(self) -> Self::IntoIter {
216 self.0.into_iter()
217 }
218}