1pub mod analyzer;
2pub mod error;
3pub mod lexer;
4pub mod loader;
5pub mod parser;
6mod position;
7
8use serde::Deserialize;
9use std::fs;
10use std::path::PathBuf;
11
12use error::HldrError;
13pub use position::Position;
14
15#[derive(Clone, Default, Debug, Deserialize)]
16pub struct Options {
17 #[serde(default)]
18 pub commit: bool,
19
20 #[serde(default = "default_data_file")]
21 pub data_file: PathBuf,
22
23 #[serde(default)]
24 pub database_conn: String,
25}
26
27impl Options {
28 pub fn new(filepath: &PathBuf) -> Result<Option<Self>, String> {
29 if !filepath.exists() {
30 return Ok(None);
31 }
32
33 if !filepath.is_file() {
34 return Err(format!("{} is not a file", filepath.display()));
35 }
36
37 let contents = fs::read_to_string(filepath).map_err(|e| e.to_string())?;
38
39 Ok(Some(toml::from_str(&contents).map_err(|e| e.to_string())?))
40 }
41}
42
43fn default_data_file() -> PathBuf {
44 PathBuf::from("place.hldr")
45}
46
47pub fn place(options: &Options) -> Result<(), HldrError> {
48 let input = fs::read_to_string(&options.data_file)?;
49 let tokens = lexer::tokenize(input.chars())?;
50 let parse_tree = parser::parse(tokens.into_iter())?;
51 let parse_tree = analyzer::analyze(parse_tree)?;
52 let mut client = loader::new_client(&options.database_conn)?;
53 let mut transaction = client.transaction()?;
54
55 loader::load(&mut transaction, parse_tree)?;
56
57 if options.commit {
58 println!("Committing changes");
59 transaction.commit()?;
60 } else {
61 println!("Rolling back changes, pass `--commit` to apply")
62 }
63
64 Ok(())
65}
66
67#[cfg(test)]
68mod root_tests {
69 }