use crate::core::{Data, link::LinkEntity};
use anyhow::Result;
use async_trait::async_trait;
use uuid::Uuid;
#[async_trait]
pub trait DataService<T: Data>: Send + Sync {
async fn create(&self, entity: T) -> Result<T>;
async fn get(&self, id: &Uuid) -> Result<Option<T>>;
async fn list(&self) -> Result<Vec<T>>;
async fn update(&self, id: &Uuid, entity: T) -> Result<T>;
async fn delete(&self, id: &Uuid) -> Result<()>;
async fn search(&self, field: &str, value: &str) -> Result<Vec<T>>;
}
#[async_trait]
pub trait LinkService: Send + Sync {
async fn create(&self, link: LinkEntity) -> Result<LinkEntity>;
async fn get(&self, id: &Uuid) -> Result<Option<LinkEntity>>;
async fn list(&self) -> Result<Vec<LinkEntity>>;
async fn find_by_source(
&self,
source_id: &Uuid,
link_type: Option<&str>,
target_type: Option<&str>,
) -> Result<Vec<LinkEntity>>;
async fn find_by_target(
&self,
target_id: &Uuid,
link_type: Option<&str>,
source_type: Option<&str>,
) -> Result<Vec<LinkEntity>>;
async fn update(&self, id: &Uuid, link: LinkEntity) -> Result<LinkEntity>;
async fn delete(&self, id: &Uuid) -> Result<()>;
async fn delete_by_entity(&self, entity_id: &Uuid) -> Result<()>;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::entity::Entity;
use chrono::{DateTime, Utc};
#[allow(dead_code)]
#[derive(Clone, Debug)]
struct TestEntity {
id: Uuid,
entity_type: String,
created_at: DateTime<Utc>,
updated_at: DateTime<Utc>,
deleted_at: Option<DateTime<Utc>>,
status: String,
name: String,
}
impl Entity for TestEntity {
type Service = ();
fn resource_name() -> &'static str {
"tests"
}
fn resource_name_singular() -> &'static str {
"test"
}
fn service_from_host(
_: &std::sync::Arc<dyn std::any::Any + Send + Sync>,
) -> Result<std::sync::Arc<Self::Service>> {
Ok(std::sync::Arc::new(()))
}
fn id(&self) -> Uuid {
self.id
}
fn entity_type(&self) -> &str {
&self.entity_type
}
fn created_at(&self) -> DateTime<Utc> {
self.created_at
}
fn updated_at(&self) -> DateTime<Utc> {
self.updated_at
}
fn deleted_at(&self) -> Option<DateTime<Utc>> {
self.deleted_at
}
fn status(&self) -> &str {
&self.status
}
}
impl Data for TestEntity {
fn name(&self) -> &str {
&self.name
}
fn indexed_fields() -> &'static [&'static str] {
&[]
}
fn field_value(&self, _field: &str) -> Option<crate::core::field::FieldValue> {
None
}
}
#[allow(dead_code)]
async fn generic_create<T, S>(service: &S, entity: T) -> Result<T>
where
T: Data,
S: DataService<T>,
{
service.create(entity).await
}
#[test]
fn test_traits_compile() {
}
}