#![warn(missing_docs)]
#![warn(clippy::all)]
pub mod policy;
pub mod prelude;
#[cfg(feature = "streams")]
pub mod stream;
pub mod transaction;
pub use async_trait::async_trait;
pub trait Repository: Send + Sync {
type Error: std::error::Error + Send + Sync;
type Pool;
fn pool(&self) -> &Self::Pool;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Pagination {
pub limit: i64,
pub offset: i64
}
impl Pagination {
pub const fn new(limit: i64, offset: i64) -> Self {
Self {
limit,
offset
}
}
pub const fn page(page: i64, per_page: i64) -> Self {
Self {
limit: per_page,
offset: page * per_page
}
}
}
impl Default for Pagination {
fn default() -> Self {
Self {
limit: 100,
offset: 0
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum SortDirection {
#[default]
Asc,
Desc
}
impl SortDirection {
pub const fn as_sql(&self) -> &'static str {
match self {
Self::Asc => "ASC",
Self::Desc => "DESC"
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum EventKind {
Created,
Updated,
SoftDeleted,
HardDeleted,
Restored
}
impl EventKind {
pub const fn is_delete(&self) -> bool {
matches!(self, Self::SoftDeleted | Self::HardDeleted)
}
pub const fn is_mutation(&self) -> bool {
!matches!(self, Self::Restored)
}
}
pub trait EntityEvent: Send + Sync + std::fmt::Debug {
type Id;
fn kind(&self) -> EventKind;
fn entity_id(&self) -> &Self::Id;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum CommandKind {
Create,
Update,
Delete,
Custom
}
impl CommandKind {
pub const fn is_create(&self) -> bool {
matches!(self, Self::Create)
}
pub const fn is_mutation(&self) -> bool {
!matches!(self, Self::Custom)
}
}
pub trait EntityCommand: Send + Sync + std::fmt::Debug {
fn kind(&self) -> CommandKind;
fn name(&self) -> &'static str;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pagination_new() {
let p = Pagination::new(50, 100);
assert_eq!(p.limit, 50);
assert_eq!(p.offset, 100);
}
#[test]
fn pagination_page() {
let p = Pagination::page(2, 25);
assert_eq!(p.limit, 25);
assert_eq!(p.offset, 50);
}
#[test]
fn pagination_default() {
let p = Pagination::default();
assert_eq!(p.limit, 100);
assert_eq!(p.offset, 0);
}
#[test]
fn sort_direction_sql() {
assert_eq!(SortDirection::Asc.as_sql(), "ASC");
assert_eq!(SortDirection::Desc.as_sql(), "DESC");
}
#[test]
fn sort_direction_default() {
assert_eq!(SortDirection::default(), SortDirection::Asc);
}
#[test]
fn event_kind_is_delete() {
assert!(!EventKind::Created.is_delete());
assert!(!EventKind::Updated.is_delete());
assert!(EventKind::SoftDeleted.is_delete());
assert!(EventKind::HardDeleted.is_delete());
assert!(!EventKind::Restored.is_delete());
}
#[test]
fn event_kind_is_mutation() {
assert!(EventKind::Created.is_mutation());
assert!(EventKind::Updated.is_mutation());
assert!(EventKind::SoftDeleted.is_mutation());
assert!(EventKind::HardDeleted.is_mutation());
assert!(!EventKind::Restored.is_mutation());
}
#[test]
fn command_kind_is_create() {
assert!(CommandKind::Create.is_create());
assert!(!CommandKind::Update.is_create());
assert!(!CommandKind::Delete.is_create());
assert!(!CommandKind::Custom.is_create());
}
#[test]
fn command_kind_is_mutation() {
assert!(CommandKind::Create.is_mutation());
assert!(CommandKind::Update.is_mutation());
assert!(CommandKind::Delete.is_mutation());
assert!(!CommandKind::Custom.is_mutation());
}
}