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
23pub const SEEDS_DIR: &str = "prax/seeds";
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28#[serde(default)]
29#[derive(Default)]
30pub struct Config {
31 pub database: DatabaseConfig,
33
34 pub generator: GeneratorConfig,
36
37 pub migrations: MigrationConfig,
39
40 pub seed: SeedConfig,
42}
43
44impl Config {
45 pub fn load(path: &Path) -> CliResult<Self> {
47 let content = std::fs::read_to_string(path)?;
48 let config: Config = toml::from_str(&content)?;
49 Ok(config)
50 }
51
52 pub fn save(&self, path: &Path) -> CliResult<()> {
54 let content = toml::to_string_pretty(self)?;
55 std::fs::write(path, content)?;
56 Ok(())
57 }
58
59 pub fn default_for_provider(provider: &str) -> Self {
61 let mut config = Self::default();
62 config.database.provider = provider.to_string();
63 config
64 }
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
69#[serde(default)]
70pub struct DatabaseConfig {
71 pub provider: String,
73
74 pub url: Option<String>,
76
77 pub shadow_url: Option<String>,
79
80 pub direct_url: Option<String>,
82
83 pub seed_path: Option<PathBuf>,
85}
86
87impl Default for DatabaseConfig {
88 fn default() -> Self {
89 Self {
90 provider: "postgresql".to_string(),
91 url: None,
92 shadow_url: None,
93 direct_url: None,
94 seed_path: None,
95 }
96 }
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize)]
101#[serde(default)]
102pub struct GeneratorConfig {
103 pub output: String,
105
106 pub features: Option<Vec<String>>,
108
109 pub prelude: Option<Vec<String>>,
111}
112
113impl Default for GeneratorConfig {
114 fn default() -> Self {
115 Self {
116 output: "./src/generated".to_string(),
117 features: None,
118 prelude: None,
119 }
120 }
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
125#[serde(default)]
126pub struct MigrationConfig {
127 pub directory: String,
129
130 pub table_name: String,
132
133 pub schema: Option<String>,
135}
136
137impl Default for MigrationConfig {
138 fn default() -> Self {
139 Self {
140 directory: MIGRATIONS_DIR.to_string(),
141 table_name: "_prax_migrations".to_string(),
142 schema: None,
143 }
144 }
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
149#[serde(default)]
150pub struct SeedConfig {
151 pub directory: String,
153
154 pub script: Option<PathBuf>,
156
157 pub auto_seed: bool,
159
160 pub environments: std::collections::HashMap<String, bool>,
163}
164
165impl Default for SeedConfig {
166 fn default() -> Self {
167 let mut environments = std::collections::HashMap::new();
168 environments.insert("development".to_string(), true);
169 environments.insert("test".to_string(), true);
170 environments.insert("staging".to_string(), false);
171 environments.insert("production".to_string(), false);
172
173 Self {
174 directory: SEEDS_DIR.to_string(),
175 script: None,
176 auto_seed: false,
177 environments,
178 }
179 }
180}
181
182impl SeedConfig {
183 pub fn should_seed(&self, environment: &str) -> bool {
185 self.environments.get(environment).copied().unwrap_or(false)
186 }
187}