Skip to main content

shared_framework/data/
mod.rs

1//! Data persistence layer built on SeaORM 2.
2//!
3//! Provides entity identity and auditing traits, a query builder with cursor
4//! pagination, a generic repository for CRUD and paginated reads, explicit
5//! relation hydration, key-value caches, database seeding, connection setup,
6//! and shared result types.
7//!
8//! Key types: [`base::BaseEntity`] and [`base::BaseAuditableEntity`] for models,
9//! [`query::QueryData`] and [`query::RepositoryOptions`] for reads,
10//! [`repository::PersistentRepository`] for database access,
11//! [`traverse`] for loading relations, [`cache`] for caching,
12//! [`seed`] for idempotent seeders, and [`types_extra`] for result wrappers.
13//!
14//! Use [`repository::PersistentRepository`] as the entry point for most
15//! database work; reach for the submodules directly for setup or advanced use.
16//!
17//!
18
19pub mod base;
20pub mod cache;
21pub mod connectors;
22pub mod query;
23pub mod repository;
24pub mod seed;
25pub mod types_extra;
26
27pub use base::{BaseAuditableEntity, BaseEntity};
28pub use query::{DeleteQueryData, NoUser, PageResult, QueryData, RepositoryOptions};
29pub use repository::PersistentRepository;
30pub use seed::{DatabaseSeeder, DatabaseSeederRunner, entity as seeder_entity};
31pub use types_extra::{
32    ChangeResultModel, EntityProjection, PaginatedResult as PaginatedResultAlias, Position,
33};
34
35/// A macro to define an enum that can be used as a SeaORM ActiveEnum with string values. This is done this way precisely because SeaORM does
36/// not support enums with string values out of the box, and this macro provides a convenient way to define such enums with the necessary traits
37/// and methods for working with them in a SeaORM context.
38#[macro_export]
39macro_rules! active_enum {
40    ($name:ident, $pg_name:literal, $( $(#[$meta:meta])* $variant:ident => $value:literal),+ $(,)?) => {
41        #[derive(Copy, Clone, Debug, PartialEq, Eq, schemars::JsonSchema, sea_orm::entity::prelude::EnumIter, sea_orm::entity::prelude::DeriveActiveEnum, serde::Serialize, serde::Deserialize)]
42        #[sea_orm(rs_type = "String", db_type = "Enum", enum_name = $pg_name, rename_all= "SCREAMING_SNAKE_CASE")]    
43        #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
44		#[doc = concat!("An enum representing a database type that is best represented as an enumeration of string values which is named `", stringify!($name), "`.")]
45		pub enum $name {
46            $(
47                $(#[$meta])*
48				$variant,
49            )+
50        }
51
52        impl $name {
53			#[doc = concat!("Returns a vector of all variants of the `", stringify!($name), "` enum.")]
54            pub fn variants() -> Vec<Self> {
55				vec![
56                    $(Self::$variant),+
57                ]
58            }
59
60			#[doc = concat!("Returns the string value associated with the `", stringify!($name), "` enum variant.")]
61            pub fn value(&self) -> String {
62                match self {
63                    $(Self::$variant => $value.to_string()),+
64                }
65            }
66
67			#[doc = concat!("Returns an `Option<", stringify!($name), ">` corresponding to the provided string value. If the value does not match any variant, `None` is returned.")]
68            pub fn from_value(value: String) -> Option<Self> {
69                Self::variants().into_iter().find(|variant| variant.value() == value)
70            }
71        }
72    };
73}