icydb_core/db/query/api/
result_ext.rs1use crate::{
8 db::{EntityResponse, ResponseError, Row},
9 prelude::*,
10 types::Id,
11};
12
13mod private {
14 use crate::{db::EntityResponse, prelude::*};
15
16 pub trait SealedResponseCardinalityExt<E: EntityKind> {}
24
25 impl<E: EntityKind> SealedResponseCardinalityExt<E> for EntityResponse<E> {}
26}
27
28use private::SealedResponseCardinalityExt;
29
30pub trait ResponseCardinalityExt<E: EntityKind>: SealedResponseCardinalityExt<E> {
39 fn require_one(&self) -> Result<(), ResponseError>;
41
42 fn require_some(&self) -> Result<(), ResponseError>;
44
45 fn try_row(self) -> Result<Option<Row<E>>, ResponseError>;
47
48 fn row(self) -> Result<Row<E>, ResponseError>;
50
51 fn try_entity(self) -> Result<Option<E>, ResponseError>;
53
54 fn entity(self) -> Result<E, ResponseError>;
56
57 fn require_id(self) -> Result<Id<E>, ResponseError>;
59}
60
61impl<E: EntityKind> ResponseCardinalityExt<E> for EntityResponse<E> {
62 fn require_one(&self) -> Result<(), ResponseError> {
63 match self.count() {
64 1 => Ok(()),
65 0 => Err(ResponseError::not_found(E::PATH)),
66 n => Err(ResponseError::not_unique(E::PATH, n)),
67 }
68 }
69
70 fn require_some(&self) -> Result<(), ResponseError> {
71 if self.is_empty() {
72 Err(ResponseError::not_found(E::PATH))
73 } else {
74 Ok(())
75 }
76 }
77
78 #[expect(clippy::cast_possible_truncation)]
79 fn try_row(self) -> Result<Option<Row<E>>, ResponseError> {
80 let mut rows = self.rows();
81
82 match rows.len() {
83 0 => Ok(None),
84 1 => Ok(rows.pop()),
85 n => Err(ResponseError::not_unique(E::PATH, n as u32)),
86 }
87 }
88
89 fn row(self) -> Result<Row<E>, ResponseError> {
90 self.try_row()?.ok_or(ResponseError::not_found(E::PATH))
91 }
92
93 fn try_entity(self) -> Result<Option<E>, ResponseError> {
94 Ok(self.try_row()?.map(Row::entity))
95 }
96
97 fn entity(self) -> Result<E, ResponseError> {
98 self.try_entity()?.ok_or(ResponseError::not_found(E::PATH))
99 }
100
101 fn require_id(self) -> Result<Id<E>, ResponseError> {
102 self.row().map(|row| row.id())
103 }
104}