nexus_memory_core/
config.rs1use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct Config {
9 pub database: DatabaseConfig,
11
12 pub server: ServerConfig,
14
15 pub embedding: EmbeddingConfig,
17
18 pub sync: SyncConfig,
20}
21
22impl Default for Config {
23 fn default() -> Self {
24 Self {
25 database: DatabaseConfig::default(),
26 server: ServerConfig::default(),
27 embedding: EmbeddingConfig::default(),
28 sync: SyncConfig::default(),
29 }
30 }
31}
32
33impl Config {
34 pub fn from_env() -> crate::Result<Self> {
36 let mut config = Self::default();
37
38 if let Ok(path) = std::env::var("NEXUS_DATABASE_PATH") {
39 config.database.path = PathBuf::from(path);
40 }
41
42 if let Ok(host) = std::env::var("NEXUS_HOST") {
43 config.server.host = host;
44 }
45
46 if let Ok(port) = std::env::var("NEXUS_PORT") {
47 config.server.port = port.parse().unwrap_or(8768);
48 }
49
50 if let Ok(enabled) = std::env::var("NEXUS_EMBEDDINGS_ENABLED") {
51 config.embedding.enabled = enabled.parse().unwrap_or(true);
52 }
53
54 if let Ok(model) = std::env::var("NEXUS_EMBEDDING_MODEL") {
55 config.embedding.model = model;
56 }
57
58 if let Ok(policy) = std::env::var("NEXUS_SYNC_POLICY") {
59 config.sync.policy = policy;
60 }
61
62 Ok(config)
63 }
64
65 pub fn database_url(&self) -> String {
67 format!("sqlite:{}", self.database.path.display())
68 }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct DatabaseConfig {
74 pub path: PathBuf,
76
77 pub foreign_keys: bool,
79
80 pub pool_size: u32,
82}
83
84impl Default for DatabaseConfig {
85 fn default() -> Self {
86 let home = std::env::var("HOME").unwrap_or_else(|_| ".".to_string());
87 let base_path = PathBuf::from(home).join(".nexus");
88
89 Self {
90 path: base_path.join("nexus.db"),
91 foreign_keys: true,
92 pool_size: 5,
93 }
94 }
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct ServerConfig {
100 pub host: String,
102
103 pub port: u16,
105
106 pub web_port: u16,
108
109 pub transport: String,
111}
112
113impl Default for ServerConfig {
114 fn default() -> Self {
115 Self {
116 host: "127.0.0.1".to_string(),
117 port: 8768,
118 web_port: 8768,
119 transport: "stdio".to_string(),
120 }
121 }
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct EmbeddingConfig {
127 pub enabled: bool,
129
130 pub model: String,
132
133 pub dimension: usize,
135}
136
137impl Default for EmbeddingConfig {
138 fn default() -> Self {
139 Self {
140 enabled: true,
141 model: "all-MiniLM-L6-v2".to_string(),
142 dimension: 384,
143 }
144 }
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct SyncConfig {
150 pub policy: String,
152
153 pub interval_secs: u64,
155}
156
157impl Default for SyncConfig {
158 fn default() -> Self {
159 Self {
160 policy: "manual".to_string(),
161 interval_secs: 300,
162 }
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169
170 #[test]
171 fn test_default_config() {
172 let config = Config::default();
173 assert!(config.embedding.enabled);
174 assert_eq!(config.embedding.dimension, 384);
175 assert_eq!(config.server.port, 8768);
176 }
177
178 #[test]
179 fn test_database_url() {
180 let config = Config::default();
181 let url = config.database_url();
182 assert!(url.starts_with("sqlite:"));
183 }
184}