From 071cb43510a58967f6c6a001763e6496faa2781f Mon Sep 17 00:00:00 2001 From: kjuulh Date: Fri, 23 Aug 2024 23:21:53 +0200 Subject: [PATCH] feat: add basic file Signed-off-by: kjuulh --- Cargo.lock | 75 ++++++++++++++++ crates/cuddle/Cargo.toml | 1 + crates/cuddle/examples/basic/cuddle.toml | 2 + crates/cuddle/src/main.rs | 108 ++++++++++++++++++----- 4 files changed, 166 insertions(+), 20 deletions(-) create mode 100644 crates/cuddle/examples/basic/cuddle.toml diff --git a/Cargo.lock b/Cargo.lock index 1353cba..bf7e84c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,6 +175,7 @@ dependencies = [ "dotenv", "serde", "tokio", + "toml", "tracing", "tracing-subscriber", "uuid", @@ -186,6 +187,12 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "getrandom" version = "0.2.15" @@ -203,6 +210,12 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "heck" version = "0.5.0" @@ -215,6 +228,16 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "indexmap" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -395,6 +418,15 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_spanned" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -491,6 +523,40 @@ dependencies = [ "syn", ] +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.40" @@ -676,3 +742,12 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] diff --git a/crates/cuddle/Cargo.toml b/crates/cuddle/Cargo.toml index f952e4a..be021a1 100644 --- a/crates/cuddle/Cargo.toml +++ b/crates/cuddle/Cargo.toml @@ -14,3 +14,4 @@ dotenv.workspace = true serde = { version = "1.0.197", features = ["derive"] } uuid = { version = "1.7.0", features = ["v4"] } +toml = "0.8.19" diff --git a/crates/cuddle/examples/basic/cuddle.toml b/crates/cuddle/examples/basic/cuddle.toml new file mode 100644 index 0000000..e6dd06e --- /dev/null +++ b/crates/cuddle/examples/basic/cuddle.toml @@ -0,0 +1,2 @@ +[project] +name = "basic" diff --git a/crates/cuddle/src/main.rs b/crates/cuddle/src/main.rs index 76c83b8..499e212 100644 --- a/crates/cuddle/src/main.rs +++ b/crates/cuddle/src/main.rs @@ -1,29 +1,97 @@ -use anyhow::Context; -use clap::{Parser, Subcommand}; - -#[derive(Parser)] -#[command(author, version, about, long_about = None, subcommand_required = true)] -struct Command { - #[command(subcommand)] - command: Option, -} - -#[derive(Subcommand)] -enum Commands { - Hello {}, -} +use project::Project; #[tokio::main] async fn main() -> anyhow::Result<()> { dotenv::dotenv().ok(); tracing_subscriber::fmt::init(); - let cli = Command::parse(); - tracing::debug!("Starting cli"); - - if let Some(Commands::Hello {}) = cli.command { - println!("Hello!") - } + Cuddle::new().await?; Ok(()) } + +struct Cuddle { + project: Option, +} + +impl Cuddle { + pub async fn new() -> anyhow::Result { + let project = Project::from_current_path().await?; + + Ok(Self { project }) + } +} + +mod project { + use std::env::current_dir; + + use serde::Deserialize; + + const CUDDLE_FILE_NAME: &str = "cuddle.toml"; + + pub struct Project { + config: Config, + } + + impl Project { + pub fn new(config: Config) -> Self { + Self { config } + } + + pub fn from_file(content: &str) -> anyhow::Result { + let config: Config = toml::from_str(&content)?; + + Ok(Self::new(config)) + } + + pub async fn from_current_path() -> anyhow::Result> { + let cur_dir = current_dir()?; + let cuddle_file = cur_dir.join(CUDDLE_FILE_NAME); + + if !cuddle_file.exists() { + // We may want to recursively search for the file (towards root) + return Ok(None); + } + + let cuddle_project_file = tokio::fs::read_to_string(cuddle_file).await?; + + Ok(Some(Self::from_file(&cuddle_project_file)?)) + } + } + + #[derive(Debug, Clone, Deserialize, PartialEq)] + pub struct Config { + project: ProjectConfig, + } + + #[derive(Debug, Clone, Deserialize, PartialEq)] + pub struct ProjectConfig { + name: String, + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn test_can_parse_simple_file() -> anyhow::Result<()> { + let project = Project::from_file( + r##" +[project] +name = "simple_file" + "##, + )?; + + assert_eq!( + Config { + project: ProjectConfig { + name: "simple_file".into() + } + }, + project.config + ); + + Ok(()) + } + } +}