1#![doc = include_str!("../README.md")]
2#![deny(missing_docs)]
3
4use core::fmt;
5use thiserror::Error;
6
7#[cfg(feature = "rusqlite")]
8use rusqlite::types::{
9 FromSql,
10 FromSqlResult,
11 ToSql,
12 ToSqlOutput,
13 ValueRef
14};
15
16#[cfg(feature = "serde")]
17use serde::{Serialize, Deserialize};
18
19#[cfg(test)]
20mod tests;
21
22pub trait Keyed {
28 type KeyType;
30
31 fn key(&self) -> Result<&Key<Self::KeyType>>;
33}
34
35pub trait Label {
39 type LabelType;
41
42 fn label(&self) -> Result<&Self::LabelType>;
44}
45
46#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
48#[derive(Clone, PartialEq, Eq, Hash, Default, Debug)]
49pub struct Tag {
50 pub key: String,
52 pub label: String,
54}
55
56pub trait Tagged {
61 fn tag(&self) -> Result<Tag>;
63 fn has_tag(&self) -> bool;
65}
66
67impl<K, T, L> Tagged for T
68where
69 T: Keyed<KeyType = K> + Label<LabelType = L>,
70 K: fmt::Display,
71 L: fmt::Display,
72{
73 fn tag(&self) -> Result<Tag> {
74 Ok(
75 Tag {
76 key: self.key()?.to_string(),
77 label: self.label()?.to_string(),
78 }
79 )
80 }
81
82 fn has_tag(&self) -> bool {
83 self.key().map(|v| v.is_some()).unwrap_or(false)
84 }
85}
86
87#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(transparent))]
93#[derive(Clone, PartialEq, Eq, Hash, Default, Debug)]
94pub struct Key<K>(pub Option<K>);
95
96impl<K> Key<K> {
97 pub fn new(value: K) -> Self {
99 Self(Some(value))
100 }
101
102 pub fn into_entity<T>(self) -> Entity<K, T> {
104 Entity::Key(self)
105 }
106
107 pub fn to_entity<T>(&self) -> Entity<K, T> where K: Clone {
109 Entity::Key(self.clone())
110 }
111}
112
113impl<K> core::ops::Deref for Key<K> {
114 type Target = Option<K>;
115
116 fn deref(&self) -> &Self::Target {
117 &self.0
118 }
119}
120
121impl<K> core::ops::DerefMut for Key<K> {
122 fn deref_mut(&mut self) -> &mut Self::Target {
123 &mut self.0
124 }
125}
126
127impl<K: fmt::Display> fmt::Display for Key<K> {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 match &self.0 {
130 Some(value) => write!(f, "{value}"),
131 None => write!(f, "None"),
132 }
133 }
134}
135
136impl<K> From<Option<K>> for Key<K> {
137 fn from(value: Option<K>) -> Self {
138 Self(value)
139 }
140}
141
142impl<K: Clone> From<&Option<K>> for Key<K> {
143 fn from(value: &Option<K>) -> Self {
144 Self(value.as_ref().cloned())
145 }
146}
147
148#[cfg(feature = "rusqlite")]
149impl<K: FromSql> FromSql for Key<K> {
150 fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
151 match value {
152 ValueRef::Null => Ok(Key(None)),
153 _ => FromSql::column_result(value).map(|v| Key(Some(v))),
154 }
155 }
156}
157
158#[cfg(feature = "rusqlite")]
159impl<K: ToSql> ToSql for Key<K> {
160 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
161 self.0.to_sql()
162 }
163}
164
165#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
172#[derive(Clone, PartialEq, Eq, Debug, Default)]
173pub enum Entity<K, T> {
174 Key(Key<K>),
176 Data(Box<T>),
178 #[default]
179 None,
181}
182
183impl<K, T> Keyed for Entity<K, T>
184where
185 T: Keyed<KeyType = K>,
186{
187 type KeyType = K;
188
189 fn key(&self) -> Result<&Key<Self::KeyType>> {
190 match self {
191 Entity::Key(key) => Ok(key),
192 Entity::Data(data) => data.key(),
193 Entity::None => Err(Error::EntityEmpty),
194 }
195 }
196}
197
198impl<K, T> Entity<K, T> {
199 pub fn data(&self) -> Result<&T> {
201 match self {
202 Entity::Data(data) => Ok(data),
203 Entity::Key(_) => Err(Error::EntityNotFetched),
204 Entity::None => Err(Error::EntityEmpty),
205 }
206 }
207
208 pub fn data_mut(&mut self) -> Result<&mut T> {
210 match self {
211 Entity::Data(ref mut data) => Ok(data),
212 Entity::Key(_) => Err(Error::EntityNotFetched),
213 Entity::None => Err(Error::EntityEmpty),
214 }
215 }
216
217 pub fn is_key(&self) -> bool {
219 matches!(self, Self::Key(..))
220 }
221
222 pub fn is_data(&self) -> bool {
224 matches!(self, Self::Data(..))
225 }
226
227 pub fn is_none(&self) -> bool {
229 matches!(self, Self::None)
230 }
231}
232
233impl<K, T> From<T> for Entity<K, T> {
234 fn from(entity: T) -> Self {
235 Self::Data(Box::new(entity))
236 }
237}
238
239#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
249#[derive(Clone, PartialEq, Eq, Debug, Default)]
250pub enum EntityLabel<K, T, L> {
251 KeyLabel(Key<K>, L),
253 Data(Box<T>),
255 #[default]
257 None,
258}
259
260impl<K, T, L> Keyed for EntityLabel<K, T, L>
261where
262 T: Keyed<KeyType = K>,
263{
264 type KeyType = K;
265
266 fn key(&self) -> Result<&Key<Self::KeyType>> {
267 match self {
268 EntityLabel::KeyLabel(key, _) => Ok(key),
269 EntityLabel::Data(data) => data.key(),
270 EntityLabel::None => Err(Error::EntityLabelEmpty),
271 }
272 }
273}
274
275impl<K, T, L> Label for EntityLabel<K, T, L>
276where
277 T: Label<LabelType = L>,
278{
279 type LabelType = L;
280
281 fn label(&self) -> Result<&Self::LabelType> {
282 match self {
283 EntityLabel::KeyLabel(_, label) => Ok(label),
284 EntityLabel::Data(data) => data.label(),
285 EntityLabel::None => Err(Error::EntityLabelEmpty),
286 }
287 }
288}
289
290impl<K, T, L> EntityLabel<K, T, L> {
291 pub fn data(&self) -> Result<&T> {
293 match self {
294 EntityLabel::Data(data) => Ok(data),
295 EntityLabel::KeyLabel(..) => Err(Error::EntityLabelNotFetched),
296 EntityLabel::None => Err(Error::EntityLabelEmpty),
297 }
298 }
299
300 pub fn data_mut(&mut self) -> Result<&mut T> {
302 match self {
303 EntityLabel::Data(ref mut data) => Ok(data),
304 EntityLabel::KeyLabel(..) => Err(Error::EntityLabelNotFetched),
305 EntityLabel::None => Err(Error::EntityLabelEmpty),
306 }
307 }
308
309 pub fn is_keylabel(&self) -> bool {
311 matches!(self, Self::KeyLabel(..))
312 }
313
314 pub fn is_data(&self) -> bool {
316 matches!(self, Self::Data(..))
317 }
318
319 pub fn is_none(&self) -> bool {
321 matches!(self, Self::None)
322 }
323}
324
325impl<K, T, L> From<T> for EntityLabel<K, T, L> {
326 fn from(entity: T) -> Self {
327 Self::Data(Box::new(entity))
328 }
329}
330
331#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
337#[derive(Clone, PartialEq, Eq, Debug, Default)]
338pub enum Many<T> {
339 Data(Vec<T>),
341 NotFetched,
343 #[default]
345 None,
346}
347
348impl<T> Many<T> {
349 pub fn data(&self) -> Result<&Vec<T>> {
351 match self {
352 Many::Data(data) => Ok(data),
353 Many::NotFetched => Err(Error::ManyNotFetched),
354 Many::None => Err(Error::ManyEmpty),
355 }
356 }
357
358 pub fn data_mut(&mut self) -> Result<&mut Vec<T>> {
360 match self {
361 Many::Data(ref mut data) => Ok(data),
362 Many::NotFetched => Err(Error::ManyNotFetched),
363 Many::None => Err(Error::ManyEmpty),
364 }
365 }
366
367 pub fn is_data(&self) -> bool {
369 matches!(self, Self::Data(..))
370 }
371
372 pub fn is_not_fetched(&self) -> bool {
374 matches!(self, Self::NotFetched)
375 }
376
377 pub fn is_none(&self) -> bool {
379 matches!(self, Self::None)
380 }
381}
382
383impl<T> From<Vec<T>> for Many<T> {
384 fn from(entities: Vec<T>) -> Self {
385 Self::Data(entities)
386 }
387}
388
389#[derive(Error, Debug)]
395pub enum Error {
396 #[error("nothing set for this Entity")]
398 EntityEmpty,
399 #[error("nothing set for this EntityLabel")]
401 EntityLabelEmpty,
402 #[error("data was not fetched from the database for this Entity")]
404 EntityNotFetched,
405 #[error("data was not fetched from the database for this EntityLabel")]
407 EntityLabelNotFetched,
408 #[error("no data set for this Many")]
410 ManyEmpty,
411 #[error("data were not fetched from the database for this Many")]
413 ManyNotFetched,
414}
415
416pub type Result<T> = core::result::Result<T, Error>;
418
419pub type Int = usize;
425pub type EntityInt<T> = Entity<Int, T>;
427pub type EntityString<T> = Entity<String, T>;
429pub type EntityLabelInt<T> = EntityLabel<Int, T, String>;
431pub type EntityLabelString<T> = EntityLabel<String, T, String>;
433
434pub mod prelude {
435 #[cfg(feature = "derive")]
445 pub use dbent_derive::{
446 Entity,
447 Label,
448 };
449
450 pub use crate::{
451 Key,
452 Keyed,
453 Label,
454 Tagged,
455 Tag,
456 Entity,
457 EntityLabel,
458 Many,
459 Int,
460 EntityInt,
461 EntityString,
462 EntityLabelInt,
463 EntityLabelString,
464 };
465}
466