use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
#[serde(default)]
pub profiles: Vec<Profile>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Profile {
pub name: String,
pub kind: BackendKind,
pub uri: String,
#[serde(default)]
pub username: Option<String>,
#[serde(default)]
pub password: Option<String>,
#[serde(default)]
pub database: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum BackendKind {
Mesh,
Neo4j,
}
impl BackendKind {
pub fn label(self) -> &'static str {
match self {
BackendKind::Mesh => "mesh",
BackendKind::Neo4j => "neo4j",
}
}
}
impl Config {
pub fn default_path() -> PathBuf {
dirs::config_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join("meshdb-client")
.join("config.toml")
}
pub fn load(path: &Path) -> Result<Self> {
if !path.exists() {
return Ok(Self::seeded());
}
let text = std::fs::read_to_string(path)
.with_context(|| format!("reading config at {}", path.display()))?;
let cfg: Self = toml::from_str(&text).context("parsing config")?;
Ok(cfg)
}
fn seeded() -> Self {
Self {
profiles: vec![
Profile {
name: "mesh-local".into(),
kind: BackendKind::Mesh,
uri: "bolt://127.0.0.1:7687".into(),
username: Some("neo4j".into()),
password: Some("password".into()),
database: None,
},
Profile {
name: "neo4j-local".into(),
kind: BackendKind::Neo4j,
uri: "bolt://127.0.0.1:7687".into(),
username: Some("neo4j".into()),
password: Some("password".into()),
database: Some("neo4j".into()),
},
],
}
}
}