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: u32 },
22}
23
24#[derive(Debug)]
30pub struct Response<E: EntityKind>(pub Vec<Row<E>>);
31
32impl<E: EntityKind> Response<E> {
33 #[must_use]
38 #[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 {
45 self.0.is_empty()
46 }
47
48 pub const fn require_one(&self) -> Result<(), ResponseError> {
53 match self.count() {
54 1 => Ok(()),
55 0 => Err(ResponseError::NotFound { entity: E::PATH }),
56 n => Err(ResponseError::NotUnique {
57 entity: E::PATH,
58 count: n,
59 }),
60 }
61 }
62
63 pub const fn require_some(&self) -> Result<(), ResponseError> {
64 if self.is_empty() {
65 Err(ResponseError::NotFound { entity: E::PATH })
66 } else {
67 Ok(())
68 }
69 }
70
71 pub fn row(self) -> Result<Row<E>, ResponseError> {
76 self.require_one()?;
77 Ok(self.0.into_iter().next().unwrap())
78 }
79
80 pub fn try_row(self) -> Result<Option<Row<E>>, ResponseError> {
81 match self.count() {
82 0 => Ok(None),
83 1 => Ok(Some(self.0.into_iter().next().unwrap())),
84 n => Err(ResponseError::NotUnique {
85 entity: E::PATH,
86 count: n,
87 }),
88 }
89 }
90
91 #[must_use]
92 pub fn rows(self) -> Vec<Row<E>> {
93 self.0
94 }
95
96 pub fn entity(self) -> Result<E, ResponseError> {
101 self.row().map(|(_, e)| e)
102 }
103
104 pub fn try_entity(self) -> Result<Option<E>, ResponseError> {
105 Ok(self.try_row()?.map(|(_, e)| e))
106 }
107
108 #[must_use]
109 pub fn entities(self) -> Vec<E> {
110 self.0.into_iter().map(|(_, e)| e).collect()
111 }
112
113 #[must_use]
118 pub fn key(&self) -> Option<Key> {
119 self.0.first().map(|(k, _)| *k)
120 }
121
122 pub fn key_strict(self) -> Result<Key, ResponseError> {
123 self.row().map(|(k, _)| k)
124 }
125
126 pub fn try_key(self) -> Result<Option<Key>, ResponseError> {
127 Ok(self.try_row()?.map(|(k, _)| k))
128 }
129
130 #[must_use]
131 pub fn keys(&self) -> Vec<Key> {
132 self.0.iter().map(|(k, _)| *k).collect()
133 }
134
135 #[must_use]
136 pub fn contains_key(&self, key: &Key) -> bool {
137 self.0.iter().any(|(k, _)| k == key)
138 }
139
140 pub fn primary_key(self) -> Result<E::PrimaryKey, ResponseError> {
145 Ok(self.entity()?.primary_key())
146 }
147
148 pub fn try_primary_key(self) -> Result<Option<E::PrimaryKey>, ResponseError> {
149 Ok(self.try_entity()?.map(|e| e.primary_key()))
150 }
151
152 #[must_use]
153 pub fn primary_keys(self) -> Vec<E::PrimaryKey> {
154 self.entities()
155 .into_iter()
156 .map(|e| e.primary_key())
157 .collect()
158 }
159
160 pub fn view(&self) -> Result<View<E>, ResponseError> {
165 self.require_one()?;
166 Ok(self
167 .0
168 .first()
169 .expect("require_one guarantees a row")
170 .1
171 .to_view())
172 }
173
174 pub fn view_opt(&self) -> Result<Option<View<E>>, ResponseError> {
175 match self.count() {
176 0 => Ok(None),
177 1 => Ok(Some(self.0[0].1.to_view())),
178 n => Err(ResponseError::NotUnique {
179 entity: E::PATH,
180 count: n,
181 }),
182 }
183 }
184
185 #[must_use]
186 pub fn views(&self) -> Vec<View<E>> {
187 self.0.iter().map(|(_, e)| e.to_view()).collect()
188 }
189}
190
191impl<E: EntityKind> IntoIterator for Response<E> {
192 type Item = Row<E>;
193 type IntoIter = std::vec::IntoIter<Self::Item>;
194
195 fn into_iter(self) -> Self::IntoIter {
196 self.0.into_iter()
197 }
198}