1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct QueryResult {
9 pub columns: Vec<String>,
11 pub rows: Vec<serde_json::Value>,
13 #[serde(rename = "execution_time_ms")]
15 pub execution_time_ms: Option<u64>,
16 #[serde(skip_serializing_if = "Option::is_none")]
18 pub error: Option<String>,
19}
20
21#[derive(Debug, Clone)]
23pub struct Row {
24 pub values: Vec<Value>,
26}
27
28impl Row {
29 pub fn from_json_value(value: &serde_json::Value) -> Option<Self> {
31 if let serde_json::Value::Array(arr) = value {
32 let values: Result<Vec<Value>, _> = arr
33 .iter()
34 .map(|v| serde_json::from_value(v.clone()))
35 .collect();
36 values.ok().map(|values| Row { values })
37 } else {
38 None
39 }
40 }
41}
42
43#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
45#[serde(untagged)]
46pub enum Value {
47 Null,
49 Bool(bool),
51 Int(i64),
53 Float(f64),
55 String(String),
57 Array(Vec<Value>),
59 Object(HashMap<String, Value>),
61}
62
63impl From<&str> for Value {
64 fn from(s: &str) -> Self {
65 Value::String(s.to_string())
66 }
67}
68
69impl From<String> for Value {
70 fn from(s: String) -> Self {
71 Value::String(s)
72 }
73}
74
75impl From<bool> for Value {
76 fn from(b: bool) -> Self {
77 Value::Bool(b)
78 }
79}
80
81impl From<i64> for Value {
82 fn from(i: i64) -> Self {
83 Value::Int(i)
84 }
85}
86
87impl From<i32> for Value {
88 fn from(i: i32) -> Self {
89 Value::Int(i as i64)
90 }
91}
92
93impl From<usize> for Value {
94 fn from(u: usize) -> Self {
95 Value::Int(u as i64)
96 }
97}
98
99impl From<f64> for Value {
100 fn from(f: f64) -> Self {
101 Value::Float(f)
102 }
103}
104
105impl From<f32> for Value {
106 fn from(f: f32) -> Self {
107 Value::Float(f as f64)
108 }
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct Node {
114 pub id: u64,
116 pub labels: Vec<String>,
118 pub properties: HashMap<String, Value>,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct Relationship {
125 pub id: u64,
127 #[serde(rename = "type")]
129 pub rel_type: String,
130 pub source_id: u64,
132 pub target_id: u64,
134 pub properties: HashMap<String, Value>,
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct DatabaseStats {
141 pub catalog: CatalogStats,
143 #[serde(rename = "label_index")]
145 pub label_index: LabelIndexStats,
146 #[serde(rename = "knn_index")]
148 pub knn_index: KnnIndexStats,
149}
150
151#[derive(Debug, Clone, Default, Serialize, Deserialize)]
153pub struct CatalogStats {
154 #[serde(rename = "label_count")]
156 pub label_count: usize,
157 #[serde(rename = "rel_type_count")]
159 pub rel_type_count: usize,
160 #[serde(rename = "node_count")]
162 pub node_count: usize,
163 #[serde(rename = "rel_count")]
165 pub rel_count: usize,
166}
167
168#[derive(Debug, Clone, Default, Serialize, Deserialize)]
170pub struct LabelIndexStats {
171 #[serde(rename = "indexed_labels")]
173 pub indexed_labels: usize,
174 #[serde(rename = "total_nodes")]
176 pub total_nodes: usize,
177}
178
179#[derive(Debug, Clone, Default, Serialize, Deserialize)]
181pub struct KnnIndexStats {
182 #[serde(rename = "total_vectors")]
184 pub total_vectors: usize,
185 pub dimension: usize,
187 #[serde(rename = "avg_search_time_us")]
189 pub avg_search_time_us: f64,
190}
191
192#[derive(Debug, Clone)]
194pub struct ClientConfig {
195 pub base_url: String,
199 pub transport: Option<crate::transport::TransportMode>,
203 pub rpc_port: u16,
205 pub resp3_port: u16,
209 pub api_key: Option<String>,
211 pub username: Option<String>,
213 pub password: Option<String>,
215 pub timeout_secs: u64,
217 pub max_retries: u32,
219}
220
221impl Default for ClientConfig {
222 fn default() -> Self {
227 Self {
228 base_url: "nexus://127.0.0.1:15475".to_string(),
229 transport: None,
230 rpc_port: 15475,
231 resp3_port: 15476,
232 api_key: None,
233 username: None,
234 password: None,
235 timeout_secs: 30,
236 max_retries: 3,
237 }
238 }
239}
240
241#[derive(Debug, Clone, Serialize)]
243pub struct CypherRequest {
244 pub query: String,
246 #[serde(skip_serializing_if = "Option::is_none")]
248 pub parameters: Option<HashMap<String, Value>>,
249}
250
251#[derive(Debug, Clone, Serialize, Deserialize)]
257pub struct DatabaseInfo {
258 pub name: String,
260 pub path: String,
262 #[serde(rename = "created_at")]
264 pub created_at: i64,
265 #[serde(rename = "node_count")]
267 pub node_count: u64,
268 #[serde(rename = "relationship_count")]
270 pub relationship_count: u64,
271 #[serde(rename = "storage_size")]
273 pub storage_size: u64,
274}
275
276#[derive(Debug, Clone, Serialize, Deserialize)]
278pub struct ListDatabasesResponse {
279 pub databases: Vec<DatabaseInfo>,
281 #[serde(rename = "default_database")]
283 pub default_database: String,
284}
285
286#[derive(Debug, Clone, Serialize)]
288pub struct CreateDatabaseRequest {
289 pub name: String,
291}
292
293#[derive(Debug, Clone, Serialize, Deserialize)]
295pub struct CreateDatabaseResponse {
296 pub success: bool,
298 pub name: String,
300 pub message: String,
302}
303
304#[derive(Debug, Clone, Serialize, Deserialize)]
306pub struct DropDatabaseResponse {
307 pub success: bool,
309 pub message: String,
311}
312
313#[derive(Debug, Clone, Serialize, Deserialize)]
315pub struct SessionDatabaseResponse {
316 pub database: String,
318}
319
320#[derive(Debug, Clone, Serialize)]
322pub struct SwitchDatabaseRequest {
323 pub name: String,
325}
326
327#[derive(Debug, Clone, Serialize, Deserialize)]
329pub struct SwitchDatabaseResponse {
330 pub success: bool,
332 pub message: String,
334}