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 primary_key(self) -> Result<E::PrimaryKey, ResponseError> {
144 Ok(self.entity()?.primary_key())
145 }
146
147 pub fn try_primary_key(self) -> Result<Option<E::PrimaryKey>, ResponseError> {
148 Ok(self.try_entity()?.map(|e| e.primary_key()))
149 }
150
151 #[must_use]
152 pub fn primary_keys(self) -> Vec<E::PrimaryKey> {
153 self.entities()
154 .into_iter()
155 .map(|e| e.primary_key())
156 .collect()
157 }
158
159 pub fn view(&self) -> Result<View<E>, ResponseError> {
164 self.require_one()?;
165 Ok(self
166 .0
167 .first()
168 .expect("require_one guarantees a row")
169 .1
170 .to_view())
171 }
172
173 pub fn view_opt(&self) -> Result<Option<View<E>>, ResponseError> {
174 match self.count() {
175 0 => Ok(None),
176 1 => Ok(Some(self.0[0].1.to_view())),
177 n => Err(ResponseError::NotUnique {
178 entity: E::PATH,
179 count: n,
180 }),
181 }
182 }
183
184 #[must_use]
185 pub fn views(&self) -> Vec<View<E>> {
186 self.0.iter().map(|(_, e)| e.to_view()).collect()
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}