1use serde::{Deserialize, Serialize};
4use std::path::{Path, PathBuf};
5
6use crate::error::CliResult;
7
8pub const CONFIG_FILE_NAME: &str = "prax.toml";
10
11pub const PRAX_DIR: &str = "prax";
13
14pub const SCHEMA_FILE_NAME: &str = "schema.prax";
16
17pub const SCHEMA_FILE_PATH: &str = "prax/schema.prax";
19
20pub const MIGRATIONS_DIR: &str = "prax/migrations";
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25#[serde(default)]
26pub struct Config {
27 pub database: DatabaseConfig,
29
30 pub generator: GeneratorConfig,
32
33 pub migrations: MigrationConfig,
35
36 pub seed: SeedConfig,
38}
39
40impl Default for Config {
41 fn default() -> Self {
42 Self {
43 database: DatabaseConfig::default(),
44 generator: GeneratorConfig::default(),
45 migrations: MigrationConfig::default(),
46 seed: SeedConfig::default(),
47 }
48 }
49}
50
51impl Config {
52 pub fn load(path: &Path) -> CliResult<Self> {
54 let content = std::fs::read_to_string(path)?;
55 let config: Config = toml::from_str(&content)?;
56 Ok(config)
57 }
58
59 pub fn save(&self, path: &Path) -> CliResult<()> {
61 let content = toml::to_string_pretty(self)?;
62 std::fs::write(path, content)?;
63 Ok(())
64 }
65
66 pub fn default_for_provider(provider: &str) -> Self {
68 let mut config = Self::default();
69 config.database.provider = provider.to_string();
70 config
71 }
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
76#[serde(default)]
77pub struct DatabaseConfig {
78 pub provider: String,
80
81 pub url: Option<String>,
83
84 pub shadow_url: Option<String>,
86
87 pub direct_url: Option<String>,
89
90 pub seed_path: Option<PathBuf>,
92}
93
94impl Default for DatabaseConfig {
95 fn default() -> Self {
96 Self {
97 provider: "postgresql".to_string(),
98 url: None,
99 shadow_url: None,
100 direct_url: None,
101 seed_path: None,
102 }
103 }
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
108#[serde(default)]
109pub struct GeneratorConfig {
110 pub output: String,
112
113 pub features: Option<Vec<String>>,
115
116 pub prelude: Option<Vec<String>>,
118}
119
120impl Default for GeneratorConfig {
121 fn default() -> Self {
122 Self {
123 output: "./src/generated".to_string(),
124 features: None,
125 prelude: None,
126 }
127 }
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
132#[serde(default)]
133pub struct MigrationConfig {
134 pub directory: String,
136
137 pub table_name: String,
139
140 pub schema: Option<String>,
142}
143
144impl Default for MigrationConfig {
145 fn default() -> Self {
146 Self {
147 directory: MIGRATIONS_DIR.to_string(),
148 table_name: "_prax_migrations".to_string(),
149 schema: None,
150 }
151 }
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize)]
156#[serde(default)]
157pub struct SeedConfig {
158 pub script: Option<PathBuf>,
160
161 pub auto_seed: bool,
163
164 pub environments: std::collections::HashMap<String, bool>,
167}
168
169impl Default for SeedConfig {
170 fn default() -> Self {
171 let mut environments = std::collections::HashMap::new();
172 environments.insert("development".to_string(), true);
173 environments.insert("test".to_string(), true);
174 environments.insert("staging".to_string(), false);
175 environments.insert("production".to_string(), false);
176
177 Self {
178 script: None,
179 auto_seed: false,
180 environments,
181 }
182 }
183}
184
185impl SeedConfig {
186 pub fn should_seed(&self, environment: &str) -> bool {
188 self.environments.get(environment).copied().unwrap_or(false)
189 }
190}