icydb_core/db/response/
mod.rs1mod grouped;
10mod paged;
11mod private;
12
13use crate::{
14 db::data::{DataRow, PersistedRow, decode_data_rows_into_entity_response},
15 prelude::*,
16 traits::EntityValue,
17 types::Id,
18 value::Value,
19};
20use thiserror::Error as ThisError;
21
22pub(in crate::db) use grouped::GroupedTextCursorPageWithTrace;
23pub use grouped::{GroupedRow, PagedGroupedExecution, PagedGroupedExecutionWithTrace};
24pub use paged::{PagedLoadExecution, PagedLoadExecutionWithTrace};
25
26pub trait ResponseRow: private::Sealed {}
34
35impl ResponseRow for GroupedRow {}
36
37impl private::Sealed for GroupedRow {}
38
39#[derive(Clone, Debug, Eq, PartialEq)]
46pub struct Row<E: EntityKind> {
47 id: Id<E>,
48 entity: E,
49}
50
51impl<E: EntityKind> Row<E> {
52 #[must_use]
54 pub const fn new(id: Id<E>, entity: E) -> Self {
55 Self { id, entity }
56 }
57
58 #[must_use]
60 pub const fn id(&self) -> Id<E> {
61 self.id
62 }
63
64 #[must_use]
66 pub fn entity(self) -> E {
67 self.entity
68 }
69
70 #[must_use]
72 pub const fn entity_ref(&self) -> &E {
73 &self.entity
74 }
75
76 #[must_use]
78 pub fn into_parts(self) -> (Id<E>, E) {
79 (self.id, self.entity)
80 }
81}
82
83impl<E: EntityKind> From<(Id<E>, E)> for Row<E> {
84 fn from(value: (Id<E>, E)) -> Self {
85 Self::new(value.0, value.1)
86 }
87}
88
89impl<E: EntityKind> private::Sealed for Row<E> {}
90
91impl<E: EntityKind> ResponseRow for Row<E> {}
92
93#[derive(Clone, Debug, Eq, PartialEq)]
101pub struct ProjectedRow<E: EntityKind> {
102 id: Id<E>,
103 values: Vec<Value>,
104}
105
106impl<E: EntityKind> ProjectedRow<E> {
107 #[must_use]
109 pub const fn new(id: Id<E>, values: Vec<Value>) -> Self {
110 Self { id, values }
111 }
112
113 #[must_use]
115 pub const fn id(&self) -> Id<E> {
116 self.id
117 }
118
119 #[must_use]
121 pub const fn values(&self) -> &[Value] {
122 self.values.as_slice()
123 }
124
125 #[must_use]
127 pub fn into_parts(self) -> (Id<E>, Vec<Value>) {
128 (self.id, self.values)
129 }
130}
131
132impl<E: EntityKind> private::Sealed for ProjectedRow<E> {}
133
134impl<E: EntityKind> ResponseRow for ProjectedRow<E> {}
135
136#[derive(Debug, ThisError)]
141pub enum ResponseError {
142 #[error("expected exactly one row, found 0 (entity {entity})")]
143 NotFound { entity: &'static str },
144
145 #[error("expected exactly one row, found {count} (entity {entity})")]
146 NotUnique { entity: &'static str, count: u32 },
147}
148
149impl ResponseError {
150 #[must_use]
152 pub const fn not_found(entity: &'static str) -> Self {
153 Self::NotFound { entity }
154 }
155
156 #[must_use]
158 pub const fn not_unique(entity: &'static str, count: u32) -> Self {
159 Self::NotUnique { entity, count }
160 }
161}
162
163#[derive(Debug)]
170pub struct Response<R: ResponseRow>(Vec<R>);
171
172pub type EntityResponse<E> = Response<Row<E>>;
179
180pub type ProjectionResponse<E> = Response<ProjectedRow<E>>;
187
188impl<R: ResponseRow> Response<R> {
189 #[must_use]
191 pub const fn new(rows: Vec<R>) -> Self {
192 Self(rows)
193 }
194
195 #[must_use]
197 pub fn from_rows<T>(rows: Vec<T>) -> Self
198 where
199 T: Into<R>,
200 {
201 Self(rows.into_iter().map(Into::into).collect())
202 }
203
204 #[must_use]
206 pub const fn len(&self) -> usize {
207 self.0.len()
208 }
209
210 #[must_use]
212 #[expect(clippy::cast_possible_truncation)]
213 pub const fn count(&self) -> u32 {
214 self.0.len() as u32
215 }
216
217 #[must_use]
219 pub const fn is_empty(&self) -> bool {
220 self.0.is_empty()
221 }
222
223 #[must_use]
225 pub fn rows(self) -> Vec<R> {
226 self.0
227 }
228
229 pub fn iter(&self) -> std::slice::Iter<'_, R> {
231 self.0.iter()
232 }
233}
234
235impl<R: ResponseRow> AsRef<[R]> for Response<R> {
236 fn as_ref(&self) -> &[R] {
237 self.0.as_slice()
238 }
239}
240
241impl<R: ResponseRow> std::ops::Deref for Response<R> {
242 type Target = [R];
243
244 fn deref(&self) -> &Self::Target {
245 self.0.as_slice()
246 }
247}
248
249impl<E: EntityKind> Response<Row<E>> {
250 #[inline(never)]
252 pub(in crate::db) fn from_data_rows(
253 rows: Vec<DataRow>,
254 ) -> Result<Self, crate::error::InternalError>
255 where
256 E: PersistedRow + EntityValue,
257 {
258 decode_data_rows_into_entity_response::<E>(rows)
259 }
260
261 #[must_use]
263 pub fn id(&self) -> Option<Id<E>> {
264 self.0.first().map(Row::id)
265 }
266
267 #[must_use]
269 pub fn entities(self) -> Vec<E> {
270 self.0.into_iter().map(Row::entity).collect()
271 }
272
273 pub fn ids(&self) -> impl Iterator<Item = Id<E>> + '_ {
275 self.0.iter().map(Row::id)
276 }
277
278 pub fn contains_id(&self, id: &Id<E>) -> bool {
280 self.0.iter().any(|row| row.id() == *id)
281 }
282}
283
284impl<R: ResponseRow> IntoIterator for Response<R> {
285 type Item = R;
286 type IntoIter = std::vec::IntoIter<Self::Item>;
287
288 fn into_iter(self) -> Self::IntoIter {
289 self.0.into_iter()
290 }
291}
292
293impl<'a, R: ResponseRow> IntoIterator for &'a Response<R> {
294 type Item = &'a R;
295 type IntoIter = std::slice::Iter<'a, R>;
296
297 fn into_iter(self) -> Self::IntoIter {
298 self.iter()
299 }
300}
301
302#[derive(Debug)]
310pub struct WriteBatchResponse<E> {
311 entities: Vec<E>,
312}
313
314impl<E> WriteBatchResponse<E> {
315 #[must_use]
317 pub const fn new(entities: Vec<E>) -> Self {
318 Self { entities }
319 }
320
321 #[must_use]
323 pub const fn len(&self) -> usize {
324 self.entities.len()
325 }
326
327 #[must_use]
329 pub const fn is_empty(&self) -> bool {
330 self.entities.is_empty()
331 }
332
333 #[must_use]
335 pub fn entities(self) -> Vec<E> {
336 self.entities
337 }
338
339 pub fn ids(&self) -> impl Iterator<Item = Id<E>> + '_
341 where
342 E: EntityValue,
343 {
344 self.entities.iter().map(EntityValue::id)
345 }
346
347 pub fn iter(&self) -> std::slice::Iter<'_, E> {
349 self.entities.iter()
350 }
351}
352
353impl<E> IntoIterator for WriteBatchResponse<E> {
354 type Item = E;
355 type IntoIter = std::vec::IntoIter<E>;
356
357 fn into_iter(self) -> Self::IntoIter {
358 self.entities.into_iter()
359 }
360}
361
362impl<'a, E> IntoIterator for &'a WriteBatchResponse<E> {
363 type Item = &'a E;
364 type IntoIter = std::slice::Iter<'a, E>;
365
366 fn into_iter(self) -> Self::IntoIter {
367 self.iter()
368 }
369}