use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QueryResult {
pub columns: Vec<String>,
pub rows: Vec<serde_json::Value>,
#[serde(rename = "execution_time_ms")]
pub execution_time_ms: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
}
#[derive(Debug, Clone)]
pub struct Row {
pub values: Vec<Value>,
}
impl Row {
pub fn from_json_value(value: &serde_json::Value) -> Option<Self> {
if let serde_json::Value::Array(arr) = value {
let values: Result<Vec<Value>, _> = arr
.iter()
.map(|v| serde_json::from_value(v.clone()))
.collect();
values.ok().map(|values| Row { values })
} else {
None
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Value {
Null,
Bool(bool),
Int(i64),
Float(f64),
String(String),
Array(Vec<Value>),
Object(HashMap<String, Value>),
}
impl From<&str> for Value {
fn from(s: &str) -> Self {
Value::String(s.to_string())
}
}
impl From<String> for Value {
fn from(s: String) -> Self {
Value::String(s)
}
}
impl From<bool> for Value {
fn from(b: bool) -> Self {
Value::Bool(b)
}
}
impl From<i64> for Value {
fn from(i: i64) -> Self {
Value::Int(i)
}
}
impl From<i32> for Value {
fn from(i: i32) -> Self {
Value::Int(i as i64)
}
}
impl From<usize> for Value {
fn from(u: usize) -> Self {
Value::Int(u as i64)
}
}
impl From<f64> for Value {
fn from(f: f64) -> Self {
Value::Float(f)
}
}
impl From<f32> for Value {
fn from(f: f32) -> Self {
Value::Float(f as f64)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Node {
pub id: u64,
pub labels: Vec<String>,
pub properties: HashMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Relationship {
pub id: u64,
#[serde(rename = "type")]
pub rel_type: String,
pub source_id: u64,
pub target_id: u64,
pub properties: HashMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseStats {
pub catalog: CatalogStats,
#[serde(rename = "label_index")]
pub label_index: LabelIndexStats,
#[serde(rename = "knn_index")]
pub knn_index: KnnIndexStats,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CatalogStats {
#[serde(rename = "label_count")]
pub label_count: usize,
#[serde(rename = "rel_type_count")]
pub rel_type_count: usize,
#[serde(rename = "node_count")]
pub node_count: usize,
#[serde(rename = "rel_count")]
pub rel_count: usize,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct LabelIndexStats {
#[serde(rename = "indexed_labels")]
pub indexed_labels: usize,
#[serde(rename = "total_nodes")]
pub total_nodes: usize,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct KnnIndexStats {
#[serde(rename = "total_vectors")]
pub total_vectors: usize,
pub dimension: usize,
#[serde(rename = "avg_search_time_us")]
pub avg_search_time_us: f64,
}
#[derive(Debug, Clone)]
pub struct ClientConfig {
pub base_url: String,
pub transport: Option<crate::transport::TransportMode>,
pub rpc_port: u16,
pub resp3_port: u16,
pub api_key: Option<String>,
pub username: Option<String>,
pub password: Option<String>,
pub timeout_secs: u64,
pub max_retries: u32,
}
impl Default for ClientConfig {
fn default() -> Self {
Self {
base_url: "nexus://127.0.0.1:15475".to_string(),
transport: None,
rpc_port: 15475,
resp3_port: 15476,
api_key: None,
username: None,
password: None,
timeout_secs: 30,
max_retries: 3,
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct CypherRequest {
pub query: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub parameters: Option<HashMap<String, Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseInfo {
pub name: String,
pub path: String,
#[serde(rename = "created_at")]
pub created_at: i64,
#[serde(rename = "node_count")]
pub node_count: u64,
#[serde(rename = "relationship_count")]
pub relationship_count: u64,
#[serde(rename = "storage_size")]
pub storage_size: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListDatabasesResponse {
pub databases: Vec<DatabaseInfo>,
#[serde(rename = "default_database")]
pub default_database: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct CreateDatabaseRequest {
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateDatabaseResponse {
pub success: bool,
pub name: String,
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DropDatabaseResponse {
pub success: bool,
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionDatabaseResponse {
pub database: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct SwitchDatabaseRequest {
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SwitchDatabaseResponse {
pub success: bool,
pub message: String,
}