1use crate::entity::{Entity, NewEntity};
4use crate::error::Result;
5use crate::project::{Project, ProjectId};
6use crate::query::{PaginatedResults, SearchQuery};
7use crate::relation::{Direction, NewRelation, Relation};
8use async_trait::async_trait;
9
10#[derive(Debug, Clone, Default)]
12pub struct Graph {
13 pub entities: Vec<Entity>,
14 pub relations: Vec<Relation>,
15}
16
17impl Graph {
18 pub fn new() -> Self {
19 Self::default()
20 }
21
22 pub fn with_entities(mut self, entities: Vec<Entity>) -> Self {
23 self.entities = entities;
24 self
25 }
26
27 pub fn with_relations(mut self, relations: Vec<Relation>) -> Self {
28 self.relations = relations;
29 self
30 }
31}
32
33#[async_trait]
37pub trait KnowledgeGraph: Send + Sync {
38 async fn create_entity(&self, entity: NewEntity, project: &ProjectId) -> Result<Entity>;
44
45 async fn get_entity(&self, name: &str, project: &ProjectId) -> Result<Option<Entity>>;
47
48 async fn get_entities(&self, names: &[String], project: &ProjectId) -> Result<Vec<Entity>>;
50
51 async fn update_entity(&self, entity: &Entity) -> Result<Entity>;
53
54 async fn delete_entity(&self, name: &str, project: &ProjectId) -> Result<()>;
56
57 async fn add_observations(
59 &self,
60 name: &str,
61 observations: Vec<String>,
62 project: &ProjectId,
63 ) -> Result<Entity>;
64
65 async fn remove_observations(
67 &self,
68 name: &str,
69 observation_ids: &[String],
70 project: &ProjectId,
71 ) -> Result<Entity>;
72
73 async fn add_tags(&self, name: &str, tags: Vec<String>, project: &ProjectId) -> Result<Entity>;
75
76 async fn remove_tags(
78 &self,
79 name: &str,
80 tags: &[String],
81 project: &ProjectId,
82 ) -> Result<Entity>;
83
84 async fn create_relation(&self, relation: NewRelation, project: &ProjectId)
90 -> Result<Relation>;
91
92 async fn get_relations(
94 &self,
95 entity_name: &str,
96 direction: Direction,
97 project: &ProjectId,
98 ) -> Result<Vec<Relation>>;
99
100 async fn delete_relation(
102 &self,
103 from: &str,
104 to: &str,
105 relation_type: &str,
106 project: &ProjectId,
107 ) -> Result<()>;
108
109 async fn read_graph(&self, project: &ProjectId) -> Result<Graph>;
115
116 async fn traverse(
118 &self,
119 start: &str,
120 depth: u32,
121 direction: Direction,
122 project: &ProjectId,
123 ) -> Result<Graph>;
124
125 async fn search(&self, query: SearchQuery) -> Result<PaginatedResults<Entity>>;
131
132 async fn list_projects(&self) -> Result<Vec<Project>>;
138
139 async fn create_project(&self, name: &str, description: Option<&str>) -> Result<Project>;
141
142 async fn get_project(&self, name: &str) -> Result<Option<Project>>;
144
145 async fn get_project_by_id(&self, id: &ProjectId) -> Result<Option<Project>>;
147
148 async fn delete_project(&self, name: &str) -> Result<()>;
150
151 async fn get_or_create_default_project(&self) -> Result<Project>;
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158
159 #[test]
160 fn test_graph_builder() {
161 let graph = Graph::new()
162 .with_entities(vec![])
163 .with_relations(vec![]);
164
165 assert!(graph.entities.is_empty());
166 assert!(graph.relations.is_empty());
167 }
168}