#![feature(async_fn_in_trait)]
#![feature(decl_macro)]
#![feature(lazy_cell)]
#![feature(let_chains)]
#![forbid(unsafe_code)]
use zino_core::{
database::Schema,
datetime::DateTime,
extension::JsonObjectExt,
model::{Mutation, Query},
Map, Uuid,
};
mod group;
mod policy;
mod resource;
mod tag;
mod user;
mod message;
mod order;
mod collection;
mod dataset;
mod source;
mod task;
mod log;
mod record;
pub use group::Group;
pub use policy::Policy;
pub use resource::Resource;
pub use tag::Tag;
pub use user::User;
pub use message::Message;
pub use order::Order;
pub use collection::Collection;
pub use dataset::Dataset;
pub use source::Source;
pub use task::Task;
pub use log::Log;
pub use record::Record;
pub trait ModelAccessor: Schema {
fn id(&self) -> Uuid;
fn name(&self) -> &str;
fn namespace(&self) -> &str;
fn visibility(&self) -> &str;
fn status(&self) -> &str;
fn description(&self) -> &str;
fn content(&self) -> ⤅
fn metrics(&self) -> ⤅
fn extras(&self) -> ⤅
fn manager_id(&self) -> Uuid;
fn maintainer_id(&self) -> Uuid;
fn created_at(&self) -> DateTime;
fn updated_at(&self) -> DateTime;
fn version(&self) -> u64;
fn edition(&self) -> u32;
#[inline]
fn has_namespace(&self, namespace: &str) -> bool {
self.namespace()
.strip_prefix(namespace)
.is_some_and(|s| s.is_empty() || s.starts_with(':'))
}
#[inline]
fn is_public(&self) -> bool {
self.visibility() == "public"
}
#[inline]
fn is_internal(&self) -> bool {
self.visibility() == "internal"
}
#[inline]
fn is_private(&self) -> bool {
self.visibility() == "private"
}
#[inline]
fn is_active(&self) -> bool {
self.status() == "active"
}
#[inline]
fn is_inactive(&self) -> bool {
self.status() == "inactive"
}
#[inline]
fn is_locked(&self) -> bool {
self.status() == "locked"
}
#[inline]
fn is_deleted(&self) -> bool {
self.status() == "deleted"
}
#[inline]
fn next_version(&self) -> u64 {
self.version() + 1
}
fn current_version_filters(&self) -> Map {
let mut filters = Map::with_capacity(2);
filters.upsert("id", self.id().to_string());
filters.upsert("version", self.version());
filters
}
fn current_version_query(&self) -> Query {
let mut query = Self::default_query();
query.append_filters(&mut self.current_version_filters());
query
}
fn next_version_filters(&self) -> Map {
let mut filters = Map::with_capacity(2);
filters.upsert("id", self.id().to_string());
filters.upsert("version", self.next_version());
filters
}
fn next_version_updates(&self) -> Map {
let mut updates = Map::with_capacity(2);
updates.upsert("updated_at", DateTime::now().to_string());
updates.upsert("version", self.next_version());
updates
}
fn next_version_mutation(&self, mut updates: Map) -> Mutation {
let mut mutation = Self::default_mutation();
mutation.append_updates(&mut updates);
mutation.append_updates(&mut self.next_version_updates());
mutation
}
#[inline]
fn next_edition(&self) -> u32 {
self.edition() + 1
}
fn current_edition_filters(&self) -> Map {
let mut filters = Map::with_capacity(2);
filters.upsert("id", self.id().to_string());
filters.upsert("edition", self.edition());
filters
}
fn current_edition_query(&self) -> Query {
let mut query = Self::default_query();
query.append_filters(&mut self.current_edition_filters());
query
}
fn next_edition_filters(&self) -> Map {
let mut filters = Map::with_capacity(2);
filters.upsert("id", self.id().to_string());
filters.upsert("edition", self.next_edition());
filters
}
fn next_edition_updates(&self) -> Map {
let mut updates = Map::with_capacity(2);
updates.upsert("updated_at", DateTime::now().to_string());
updates.upsert("version", self.next_version());
updates.upsert("edition", self.next_edition());
updates
}
fn next_edition_mutation(&self, mut updates: Map) -> Mutation {
let mut mutation = Self::default_mutation();
mutation.append_updates(&mut updates);
mutation.append_updates(&mut self.next_edition_updates());
mutation
}
fn soft_delete_mutation(&self) -> Mutation {
let mut mutation = Self::default_mutation();
let mut updates = self.next_edition_updates();
updates.upsert("status", "deleted");
mutation.append_updates(&mut updates);
mutation
}
#[inline]
fn default_list_query() -> Query {
let mut query = Self::default_query();
query.add_filter("status", Map::from_entry("$ne", "deleted"));
query.set_sort_order("updated_at".to_owned(), false);
query
}
}
macro impl_model_accessor($model:ty, $id:ident, $name:ident, $namespace:ident, $visibility:ident,
$status:ident, $description:ident, $content:ident, $metrics:ident, $extras:ident,
$manager_id:ident, $maintainer_id:ident, $created_at:ident, $updated_at:ident,
$version:ident, $edition:ident) {
impl ModelAccessor for $model {
#[inline]
fn id(&self) -> Uuid {
self.$id
}
#[inline]
fn name(&self) -> &str {
&self.$name
}
#[inline]
fn namespace(&self) -> &str {
&self.$namespace
}
#[inline]
fn visibility(&self) -> &str {
&self.$visibility
}
#[inline]
fn status(&self) -> &str {
&self.$status
}
#[inline]
fn description(&self) -> &str {
&self.$description
}
#[inline]
fn content(&self) -> &Map {
&self.$content
}
#[inline]
fn metrics(&self) -> &Map {
&self.$metrics
}
#[inline]
fn extras(&self) -> &Map {
&self.$extras
}
#[inline]
fn manager_id(&self) -> Uuid {
self.$manager_id
}
#[inline]
fn maintainer_id(&self) -> Uuid {
self.$maintainer_id
}
#[inline]
fn created_at(&self) -> DateTime {
self.$created_at
}
#[inline]
fn updated_at(&self) -> DateTime {
self.$updated_at
}
#[inline]
fn version(&self) -> u64 {
self.$version
}
#[inline]
fn edition(&self) -> u32 {
self.$edition
}
}
}