1use crate::core::{link::LinkEntity, Data};
4use anyhow::Result;
5use async_trait::async_trait;
6use uuid::Uuid;
7
8#[async_trait]
13pub trait DataService<T: Data>: Send + Sync {
14 async fn create(&self, entity: T) -> Result<T>;
16
17 async fn get(&self, id: &Uuid) -> Result<Option<T>>;
19
20 async fn list(&self) -> Result<Vec<T>>;
22
23 async fn update(&self, id: &Uuid, entity: T) -> Result<T>;
25
26 async fn delete(&self, id: &Uuid) -> Result<()>;
28
29 async fn search(&self, field: &str, value: &str) -> Result<Vec<T>>;
31}
32
33#[async_trait]
38pub trait LinkService: Send + Sync {
39 async fn create(&self, link: LinkEntity) -> Result<LinkEntity>;
41
42 async fn get(&self, id: &Uuid) -> Result<Option<LinkEntity>>;
44
45 async fn list(&self) -> Result<Vec<LinkEntity>>;
47
48 async fn find_by_source(
52 &self,
53 source_id: &Uuid,
54 link_type: Option<&str>,
55 target_type: Option<&str>,
56 ) -> Result<Vec<LinkEntity>>;
57
58 async fn find_by_target(
62 &self,
63 target_id: &Uuid,
64 link_type: Option<&str>,
65 source_type: Option<&str>,
66 ) -> Result<Vec<LinkEntity>>;
67
68 async fn update(&self, id: &Uuid, link: LinkEntity) -> Result<LinkEntity>;
74
75 async fn delete(&self, id: &Uuid) -> Result<()>;
77
78 async fn delete_by_entity(&self, entity_id: &Uuid) -> Result<()>;
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use crate::core::entity::Entity;
88 use chrono::{DateTime, Utc};
89
90 #[allow(dead_code)]
92 #[derive(Clone, Debug)]
93 struct TestEntity {
94 id: Uuid,
95 entity_type: String,
96 created_at: DateTime<Utc>,
97 updated_at: DateTime<Utc>,
98 deleted_at: Option<DateTime<Utc>>,
99 status: String,
100 name: String,
101 }
102
103 impl Entity for TestEntity {
104 type Service = ();
105
106 fn resource_name() -> &'static str {
107 "tests"
108 }
109
110 fn resource_name_singular() -> &'static str {
111 "test"
112 }
113
114 fn service_from_host(
115 _: &std::sync::Arc<dyn std::any::Any + Send + Sync>,
116 ) -> Result<std::sync::Arc<Self::Service>> {
117 Ok(std::sync::Arc::new(()))
118 }
119
120 fn id(&self) -> Uuid {
121 self.id
122 }
123
124 fn entity_type(&self) -> &str {
125 &self.entity_type
126 }
127
128 fn created_at(&self) -> DateTime<Utc> {
129 self.created_at
130 }
131
132 fn updated_at(&self) -> DateTime<Utc> {
133 self.updated_at
134 }
135
136 fn deleted_at(&self) -> Option<DateTime<Utc>> {
137 self.deleted_at
138 }
139
140 fn status(&self) -> &str {
141 &self.status
142 }
143 }
144
145 impl Data for TestEntity {
146 fn name(&self) -> &str {
147 &self.name
148 }
149
150 fn indexed_fields() -> &'static [&'static str] {
151 &[]
152 }
153
154 fn field_value(&self, _field: &str) -> Option<crate::core::field::FieldValue> {
155 None
156 }
157 }
158
159 #[allow(dead_code)]
161 async fn generic_create<T, S>(service: &S, entity: T) -> Result<T>
162 where
163 T: Data,
164 S: DataService<T>,
165 {
166 service.create(entity).await
167 }
168
169 #[test]
170 fn test_traits_compile() {
171 }
174}