icydb_core/db/
response.rs1use crate::{prelude::*, view::View};
2use thiserror::Error as ThisError;
3
4pub type Row<E> = (Key, E);
9
10#[derive(Debug, ThisError)]
16pub enum ResponseError {
17 #[error("expected exactly one row, found 0 (entity {entity})")]
18 NotFound { entity: &'static str },
19
20 #[error("expected exactly one row, found {count} (entity {entity})")]
21 NotUnique { entity: &'static str, count: u64 },
22}
23
24#[derive(Debug)]
30pub struct Response<E: EntityKind>(pub Vec<Row<E>>);
31
32impl<E: EntityKind> Response<E> {
33 #[must_use]
38 pub const fn count(&self) -> u64 {
39 self.0.len() as u64
40 }
41
42 #[must_use]
43 pub const fn is_empty(&self) -> bool {
44 self.0.is_empty()
45 }
46
47 pub const fn require_one(&self) -> Result<(), ResponseError> {
52 match self.count() {
53 1 => Ok(()),
54 0 => Err(ResponseError::NotFound { entity: E::PATH }),
55 n => Err(ResponseError::NotUnique {
56 entity: E::PATH,
57 count: n,
58 }),
59 }
60 }
61
62 pub const fn require_some(&self) -> Result<(), ResponseError> {
63 if self.is_empty() {
64 Err(ResponseError::NotFound { entity: E::PATH })
65 } else {
66 Ok(())
67 }
68 }
69
70 pub fn row(self) -> Result<Row<E>, ResponseError> {
75 self.require_one()?;
76 Ok(self.0.into_iter().next().unwrap())
77 }
78
79 pub fn try_row(self) -> Result<Option<Row<E>>, ResponseError> {
80 match self.count() {
81 0 => Ok(None),
82 1 => Ok(Some(self.0.into_iter().next().unwrap())),
83 n => Err(ResponseError::NotUnique {
84 entity: E::PATH,
85 count: n,
86 }),
87 }
88 }
89
90 #[must_use]
91 pub fn rows(self) -> Vec<Row<E>> {
92 self.0
93 }
94
95 pub fn entity(self) -> Result<E, ResponseError> {
100 self.row().map(|(_, e)| e)
101 }
102
103 pub fn try_entity(self) -> Result<Option<E>, ResponseError> {
104 Ok(self.try_row()?.map(|(_, e)| e))
105 }
106
107 #[must_use]
108 pub fn entities(self) -> Vec<E> {
109 self.0.into_iter().map(|(_, e)| e).collect()
110 }
111
112 #[must_use]
117 pub fn key(&self) -> Option<Key> {
118 self.0.first().map(|(k, _)| *k)
119 }
120
121 pub fn key_strict(self) -> Result<Key, ResponseError> {
122 self.row().map(|(k, _)| k)
123 }
124
125 pub fn try_key(self) -> Result<Option<Key>, ResponseError> {
126 Ok(self.try_row()?.map(|(k, _)| k))
127 }
128
129 #[must_use]
130 pub fn keys(&self) -> Vec<Key> {
131 self.0.iter().map(|(k, _)| *k).collect()
132 }
133
134 #[must_use]
135 pub fn contains_key(&self, key: &Key) -> bool {
136 self.0.iter().any(|(k, _)| k == key)
137 }
138
139 pub fn view(&self) -> Result<View<E>, ResponseError> {
144 self.require_one()?;
145 Ok(self
146 .0
147 .first()
148 .expect("require_one guarantees a row")
149 .1
150 .to_view())
151 }
152
153 pub fn view_opt(&self) -> Result<Option<View<E>>, ResponseError> {
154 match self.count() {
155 0 => Ok(None),
156 1 => Ok(Some(self.0[0].1.to_view())),
157 n => Err(ResponseError::NotUnique {
158 entity: E::PATH,
159 count: n,
160 }),
161 }
162 }
163
164 #[must_use]
165 pub fn views(&self) -> Vec<View<E>> {
166 self.0.iter().map(|(_, e)| e.to_view()).collect()
167 }
168
169 #[must_use]
175 pub fn first(self) -> Option<Row<E>> {
176 self.0.into_iter().next()
177 }
178
179 #[must_use]
180 pub fn first_entity(self) -> Option<E> {
181 self.first().map(|(_, e)| e)
182 }
183
184 #[must_use]
185 pub fn first_pk(self) -> Option<E::PrimaryKey> {
186 self.first_entity().map(|e| e.primary_key())
187 }
188}
189
190impl<E: EntityKind> IntoIterator for Response<E> {
191 type Item = Row<E>;
192 type IntoIter = std::vec::IntoIter<Self::Item>;
193
194 fn into_iter(self) -> Self::IntoIter {
195 self.0.into_iter()
196 }
197}