starfish_core/lang/
mod.rs

1//! Abstract Syntax Tree for the query language, constructed using JSON
2
3/// Structure of a schema request
4pub mod schema;
5
6/// Structure of a mutate request
7pub mod mutate;
8
9/// Structure of a query request
10pub mod query;
11
12use std::collections::HashMap;
13
14use serde::{Deserialize, Serialize};
15use serde_json::Value as JsonValue;
16
17use crate::schema::{format_edge_table_name, format_node_attribute_name, format_node_table_name};
18
19use super::entities::entity_attribute::Datatype;
20
21/// Structure of entity, deserialized as struct from json
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct EntityJson {
24    /// Name of entity
25    pub name: String,
26    /// Additional attributes
27    pub attributes: Vec<EntityAttrJson>,
28}
29
30/// Structure of entity attribute, deserialized as struct from json
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct EntityAttrJson {
33    /// Name of attribute
34    pub name: String,
35    /// Datatype, to determine how to store the value in database
36    pub datatype: Datatype,
37}
38
39impl EntityJson {
40    /// Prefix the name of node table
41    pub fn get_table_name(&self) -> String {
42        format_node_table_name(&self.name)
43    }
44}
45
46impl EntityAttrJson {
47    /// Prefix the column name of entity attribute
48    pub fn get_column_name(&self) -> String {
49        format_node_attribute_name(&self.name)
50    }
51}
52
53/// Structure of relation, deserialized as struct from json
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct RelationJson {
56    /// Name of relation
57    pub name: String,
58    /// Name of related entity (from side)
59    pub from_entity: String,
60    /// Name of related entity (to side)
61    pub to_entity: String,
62    /// Directed relation
63    pub directed: bool,
64}
65
66impl RelationJson {
67    /// Prefix the name of relation table
68    pub fn get_table_name(&self) -> String {
69        format_edge_table_name(&self.name)
70    }
71}
72
73/// Structure of a edge, deserialized as struct from json
74#[derive(Debug, Clone, Deserialize, Serialize)]
75pub struct EdgeJson {
76    /// Name of relation
77    pub name: String,
78    /// Name of related node (from side)
79    pub from_node: String,
80    /// Name of related node (to side)
81    pub to_node: String,
82}
83
84/// Structure of a edge, deserialized as struct from json
85#[derive(Debug, Clone, Deserialize, Serialize)]
86pub struct ClearEdgeJson {
87    /// Name of relation
88    pub name: String,
89    /// Name of node
90    pub node: String,
91}
92
93/// Structure of a node, deserialized as struct from json
94#[derive(Debug, Clone, Deserialize, Serialize)]
95pub struct NodeJson {
96    /// Name of entity this node belongs to
97    pub of: String,
98    /// Name of node
99    pub name: String,
100    /// Additional attributes
101    pub attributes: HashMap<String, JsonValue>,
102}
103
104/// Structure of a node in batch, deserialized as struct from json
105#[derive(Debug, Clone, Deserialize, Serialize)]
106pub struct Node {
107    /// Name of node
108    pub name: String,
109    /// Additional attributes
110    pub attributes: HashMap<String, JsonValue>,
111}
112
113impl Node {
114    /// Construct a new Node with no attributes
115    pub fn new<S>(name: S) -> Self
116    where
117        S: Into<String>,
118    {
119        Self {
120            name: name.into(),
121            attributes: Default::default(),
122        }
123    }
124
125    /// Construct a vector of new Nodes with no attributes
126    pub fn new_vec<S>(names: Vec<S>) -> Vec<Self>
127    where
128        S: Into<String>,
129    {
130        names.into_iter().map(Self::new).collect()
131    }
132}
133
134/// Structure of nodes in batch, deserialized as struct from json
135#[derive(Debug, Clone, Deserialize, Serialize)]
136pub struct NodeJsonBatch {
137    /// Name of entity this node belongs to
138    pub of: String,
139    /// Vector of nodes
140    pub nodes: Vec<Node>,
141}
142
143/// Structure of a edge in batch, deserialized as struct from json
144#[derive(Debug, Clone, Deserialize, Serialize)]
145pub struct Edge {
146    /// Name of related node (from side)
147    pub from_node: String,
148    /// Name of related node (to side)
149    pub to_node: String,
150}
151
152impl Edge {
153    /// Construct a new Edge
154    pub fn new<SFrom, STo>(from: SFrom, to: STo) -> Self
155    where
156        SFrom: Into<String>,
157        STo: Into<String>,
158    {
159        Self {
160            from_node: from.into(),
161            to_node: to.into(),
162        }
163    }
164
165    /// Construct a vector of new Edges
166    pub fn new_vec<SFrom, STo>(pairs: Vec<(SFrom, STo)>) -> Vec<Self>
167    where
168        SFrom: Into<String>,
169        STo: Into<String>,
170    {
171        pairs
172            .into_iter()
173            .map(|(from, to)| Self::new(from, to))
174            .collect()
175    }
176}
177
178/// Structure of edges in batch, deserialized as struct from json
179#[derive(Debug, Clone, Deserialize, Serialize)]
180pub struct EdgeJsonBatch {
181    /// Name of relation
182    pub of: String,
183    /// Vector of edges
184    pub edges: Vec<Edge>,
185}
186
187/// Structure of the connectivity in a 'sortBy' constraint used in a query request, deserialized as struct from json
188#[derive(Debug, Clone, Serialize, Deserialize)]
189#[serde(rename_all = "camelCase")]
190pub enum ConnectivityTypeJson {
191    /// Simple in-connectivity
192    Simple,
193    /// Compound in-connectivity
194    Compound,
195    /// Complex in-connectivity with decay factor 0.3
196    Complex03,
197    /// Complex in-connectivity with decay factor 0.5
198    Complex05,
199    /// Complex in-connectivity with decay factor 0.7
200    Complex07,
201    /// out-connectivity
202    Out,
203}
204
205impl Default for ConnectivityTypeJson {
206    fn default() -> Self {
207        Self::Simple
208    }
209}
210
211impl ConnectivityTypeJson {
212    /// Convert self to the corresponding column name in the entity table
213    pub fn to_column_name<S: Into<String>>(self, relation_name: S) -> String {
214        format!(
215            "{}_{}",
216            relation_name.into(),
217            match self {
218                Self::Simple => "in_conn",
219                Self::Compound => "in_conn_compound",
220                Self::Complex03 => "in_conn_complex03",
221                Self::Complex05 => "in_conn_complex05",
222                Self::Complex07 => "in_conn_complex07",
223                Self::Out => "out_conn",
224            }
225        )
226    }
227}