icydb_core/db/response/
mod.rs

1use crate::{Error, Key, ThisError, db::DbError, traits::EntityKind};
2
3///
4/// ResponseError
5///
6
7#[derive(Debug, ThisError)]
8pub enum ResponseError {
9    #[error("expected one or more rows, found 0 (entity {0})")]
10    NoRowsFound(String),
11}
12
13impl From<ResponseError> for Error {
14    fn from(err: ResponseError) -> Self {
15        DbError::from(err).into()
16    }
17}
18
19///
20/// Response
21///
22
23#[derive(Debug)]
24pub struct Response<E: EntityKind>(pub Vec<(Key, E)>);
25
26impl<E> Response<E>
27where
28    E: EntityKind,
29{
30    // count
31    // not len, as it returns a u32 so could get confusing
32    #[must_use]
33    #[allow(clippy::cast_possible_truncation)]
34    pub const fn count(&self) -> u32 {
35        self.0.len() as u32
36    }
37
38    #[must_use]
39    pub const fn is_empty(&self) -> bool {
40        self.0.is_empty()
41    }
42
43    ///
44    /// Key
45    ///
46
47    #[must_use]
48    pub fn key(&self) -> Option<Key> {
49        self.0.first().map(|(key, _)| *key)
50    }
51
52    pub fn try_key(&self) -> Result<Key, Error> {
53        let key = self
54            .key()
55            .ok_or_else(|| ResponseError::NoRowsFound(E::PATH.to_string()))?;
56
57        Ok(key)
58    }
59
60    #[must_use]
61    pub fn keys(&self) -> Vec<Key> {
62        self.0.iter().map(|(key, _)| *key).collect()
63    }
64
65    pub fn keys_iter(self) -> impl Iterator<Item = Key> {
66        self.0.into_iter().map(|(key, _)| key)
67    }
68
69    ///
70    /// Pk
71    ///
72
73    #[must_use]
74    pub fn pk(&self) -> Option<E::PrimaryKey> {
75        self.0.first().map(|(_, e)| e.primary_key())
76    }
77
78    pub fn try_pk(&self) -> Result<E::PrimaryKey, Error> {
79        let pk = self
80            .pk()
81            .ok_or_else(|| ResponseError::NoRowsFound(E::PATH.to_string()))?;
82
83        Ok(pk)
84    }
85
86    #[must_use]
87    pub fn pks(&self) -> Vec<E::PrimaryKey> {
88        self.0.iter().map(|(_, e)| e.primary_key()).collect()
89    }
90
91    pub fn pks_iter(self) -> impl Iterator<Item = E::PrimaryKey> {
92        self.0.into_iter().map(|(_, e)| e.primary_key())
93    }
94
95    ///
96    /// Entity
97    ///
98
99    #[must_use]
100    pub fn entity(self) -> Option<E> {
101        self.0.into_iter().next().map(|(_, e)| e)
102    }
103
104    pub fn try_entity(self) -> Result<E, Error> {
105        let res = self
106            .entity()
107            .ok_or_else(|| ResponseError::NoRowsFound(E::PATH.to_string()))?;
108
109        Ok(res)
110    }
111
112    #[must_use]
113    pub fn entities(self) -> Vec<E> {
114        self.0.into_iter().map(|(_, e)| e).collect()
115    }
116
117    pub fn entities_iter(self) -> impl Iterator<Item = E> {
118        self.0.into_iter().map(|(_, e)| e)
119    }
120
121    ///
122    /// View
123    ///
124
125    #[must_use]
126    pub fn view(self) -> Option<E::ViewType> {
127        self.entity().map(|e| e.to_view())
128    }
129
130    pub fn try_view(self) -> Result<E::ViewType, Error> {
131        self.try_entity().map(|e| e.to_view())
132    }
133
134    #[must_use]
135    pub fn views(self) -> Vec<E::ViewType> {
136        self.entities().into_iter().map(|e| e.to_view()).collect()
137    }
138
139    pub fn views_iter(self) -> impl Iterator<Item = E::ViewType> {
140        self.entities().into_iter().map(|e| e.to_view())
141    }
142}
143
144impl<E: EntityKind> IntoIterator for Response<E> {
145    type Item = (Key, E);
146    type IntoIter = std::vec::IntoIter<Self::Item>;
147
148    fn into_iter(self) -> Self::IntoIter {
149        self.0.into_iter()
150    }
151}