summary refs log tree commit diff stats
path: root/src/main.rs
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-03-31 21:57:01 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-03-31 21:57:01 +0200
commit2e5e4b5736c446198e36760e254b7c17dd987166 (patch)
treeb74915864a2c80dbc0a0ebe26a52140a934f45c5 /src/main.rs
parentdocs(example): Add an example directory (diff)
downloadlpm-2e5e4b5736c446198e36760e254b7c17dd987166.tar.gz
lpm-2e5e4b5736c446198e36760e254b7c17dd987166.zip
refactor(treewide): Improve code quality by working with a FileTree
The FileTree has been taken from the implementation written by my for the
Trinitrix project. It alleviates the problem, where functions had to do
many things themselves.
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs127
1 files changed, 100 insertions, 27 deletions
diff --git a/src/main.rs b/src/main.rs
index b19e7bf..8c2ea62 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,38 +1,111 @@
+use std::{env, ffi::OsString, fs, path::PathBuf};
+
+use anyhow::{bail, Context};
 use clap::Parser;
-use command_line_interface::{
-    Args,
-    Command::New,
-    SubCommand::{Chapter, Section},
+use log::debug;
+
+use crate::{
+    cli::{
+        Args,
+        Command::New,
+        What::{Chapter, Section},
+    },
+    config_file::Config,
+    new::{chapter::generate_new_chapter, section::generate_new_section},
 };
-use new::{chapter::generate_new_chapter, section::generate_new_section};
 
-pub mod command_line_interface;
-pub mod data;
+pub mod cli;
+pub mod config_file;
 pub mod new;
 
-fn main() {
+// The copyright header tells you, where this file is from.
+pub mod file_tree;
+
+fn main() -> anyhow::Result<()> {
+    env_logger::init();
     let args = Args::parse();
 
-    match args.cli {
+    let project_root = get_project_root_by_lmp_toml().context("Looking for the project root")?;
+
+    let config_file = fs::read_to_string(project_root.join("lpm.toml"))?;
+    let config: Config = toml::from_str(&config_file).context("Reading toml from string")?;
+
+    let file_tree = match args.cli {
         New(new_command) => match new_command {
-            Section { name } => generate_new_section(name).unwrap(),
-            Chapter { name } => generate_new_chapter(name).unwrap(),
-            //            Project {
-            //                name,
-            //                first_chapter,
-            //                //first_section,
-            //            } => {
-            //                let preamble_path = PathBuf::from("");
-            //                let resource_path = PathBuf::from("");
-            //                generate_new_project(
-            //                    name,
-            //                    first_chapter,
-            //                    //first_section,
-            //                    preamble_path,
-            //                    resource_path,
-            //                )
-            //                .unwrap()
-            //            }
+            Section { name, chapter } => {
+                let chapter = if let Some(val) = chapter {
+                    // The user probably has not added the preceeding chapter number to the chapter
+                    // string
+                    if val.starts_with(|c: char| c.is_numeric()) {
+                        eprintln!(
+                            "Your chapter name starts with a number, assuming \
+                            that you have already added the chapter number"
+                        );
+                        val
+                    } else {
+                        bail!(
+                            "Calculating the chapter number is not yet \
+                            implemented, please add it yourself"
+                        );
+                    }
+                } else {
+                    // The user thinks that they are already inside a chapter
+                    get_upwards_chapter()?
+                };
+
+                generate_new_section(&config, name, &project_root, &chapter)?
+            }
+            Chapter { name } => generate_new_chapter(config, &project_root, name)?,
         },
+    };
+
+    file_tree.materialize()?;
+
+    Ok(())
+}
+
+pub fn get_project_root_by_lmp_toml() -> anyhow::Result<PathBuf> {
+    let path = env::current_dir()?;
+    let mut path_ancestors = path.as_path().ancestors();
+
+    while let Some(path_segment) = path_ancestors.next() {
+        if fs::read_dir(path_segment)?.into_iter().any(|path_segment| {
+            path_segment
+                .expect("The read_dir shouldn't error out here")
+                .file_name()
+                == OsString::from("lpm.toml")
+        }) {
+            return Ok(PathBuf::from(path_segment));
+        }
     }
+    bail!("Ran out of places to find lpm.toml")
+}
+
+fn get_upwards_chapter() -> anyhow::Result<String> {
+    let current_path = env::current_dir()?;
+
+    for anc in current_path.as_path().ancestors() {
+        debug!("Reading directory {}", anc.display());
+
+        for dir in fs::read_dir(anc)? {
+            let dir = dir?;
+            debug!("Checking path: {}", dir.file_name().to_string_lossy());
+
+            if dir.file_name() == OsString::from("chapter.tex") {
+                match anc
+                    .file_name()
+                    .expect("This should always be a file")
+                    .to_str()
+                {
+                    Some(str) => return Ok(str.to_owned()),
+                    None => bail!(
+                        "Failed to convert your path ('{}') to a string!",
+                        dir.file_name().to_string_lossy()
+                    ),
+                }
+            }
+        }
+    }
+
+    bail!("Failed to get a chapter name, please specify one with the `--chapter` flag!")
 }