From 96374b6491a17412b7eef284759e4fd29b1797f5 Mon Sep 17 00:00:00 2001 From: Schrottkatze Date: Fri, 12 Jan 2024 09:36:30 +0100 Subject: [PATCH] split up modules into subfiles --- crates/app/src/cli.rs | 12 +++ crates/app/src/config.rs | 74 ++++++++++++++ crates/app/src/error_reporting.rs | 37 +++++++ crates/app/src/main.rs | 155 +----------------------------- crates/app/src/welcome_msg.rs | 13 +++ 5 files changed, 140 insertions(+), 151 deletions(-) create mode 100644 crates/app/src/cli.rs create mode 100644 crates/app/src/config.rs create mode 100644 crates/app/src/error_reporting.rs create mode 100644 crates/app/src/welcome_msg.rs diff --git a/crates/app/src/cli.rs b/crates/app/src/cli.rs new file mode 100644 index 0000000..30754c5 --- /dev/null +++ b/crates/app/src/cli.rs @@ -0,0 +1,12 @@ +use std::path::PathBuf; + +use clap::Parser; + +#[derive(Parser)] +pub(crate) struct Args { + /// Read this config file. + #[arg(short, long)] + pub config_file: Option, + #[arg(long, env = "NO_STARTUP_MESSAGE", default_value = "false")] + pub no_startup_message: bool, +} diff --git a/crates/app/src/config.rs b/crates/app/src/config.rs new file mode 100644 index 0000000..86f6763 --- /dev/null +++ b/crates/app/src/config.rs @@ -0,0 +1,74 @@ +use std::{ + fs, + path::{Path, PathBuf}, + process, +}; + +use serde::{Deserialize, Serialize}; + +use crate::error_reporting::{report_serde_json_err, report_serde_ron_err}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Configs { + #[serde(default = "default_example_value")] + pub example_value: i32, + #[serde(default = "default_no_startup_msg")] + pub no_startup_message: bool, +} + +/// what the fuck serde why do i need this +fn default_example_value() -> i32 { + 43 +} +fn default_no_startup_msg() -> bool { + false +} + +impl Configs { + pub fn read(custom_path: Option) -> Self { + use owo_colors::OwoColorize; + let p = match custom_path { + Some(p) => p, + None => { + let config_path = dirs::config_dir().expect("config dir should exist"); + + let ron_path = config_path.with_file_name("config.ron"); + let json_path = config_path.with_file_name("config.json"); + + if Path::new(&ron_path).exists() { + ron_path + } else if Path::new(&json_path).exists() { + json_path + } else { + eprintln!("{}: couldn't find config file", "Fatal error".red()); + process::exit(1) + } + } + }; + + match p.extension().map(|v| v.to_str().unwrap()) { + Some("ron") => Self::read_json(&fs::read_to_string(p).unwrap()), + Some("json") => Self::read_ron(&fs::read_to_string(p).unwrap()), + None | Some(_) => { + eprintln!( + "{}: couldn't determine config file type", + "Fatal error".red() + ); + process::exit(1) + } + } + } + pub fn read_json(config_text: &str) -> Configs { + match serde_json::from_str(config_text) { + Ok(c) => c, + Err(e) => report_serde_json_err(config_text, e), + } + } + + pub fn read_ron(config_text: &str) -> Configs { + match ron::from_str(config_text) { + Ok(c) => c, + Err(e) => report_serde_ron_err(config_text, e), + } + } +} diff --git a/crates/app/src/error_reporting.rs b/crates/app/src/error_reporting.rs new file mode 100644 index 0000000..f71e10d --- /dev/null +++ b/crates/app/src/error_reporting.rs @@ -0,0 +1,37 @@ +use std::process; + +use ron::error::Position; + +pub fn report_serde_json_err(src: &str, err: serde_json::Error) -> ! { + report_serde_err(src, err.line(), err.column(), err.to_string()) +} + +pub fn report_serde_ron_err(src: &str, err: ron::error::SpannedError) -> ! { + let Position { line, col } = err.position; + report_serde_err(src, line, col, err.to_string()) +} + +pub fn report_serde_err(src: &str, line: usize, col: usize, msg: String) -> ! { + use ariadne::{Label, Report, Source}; + let offset = try_reconstruct_loc(src, line, col); + + Report::build(ariadne::ReportKind::Error, "test", offset) + .with_label(Label::new(("test", offset..offset)).with_message("Something went wrong here!")) + .with_message(msg) + .with_note("We'd like to give better errors, but serde errors are horrible to work with...") + .finish() + .print(("test", Source::from(src))) + .unwrap(); + process::exit(1); +} +fn try_reconstruct_loc(src: &str, line_nr: usize, col_nr: usize) -> usize { + let (line_nr, col_nr) = (line_nr - 1, col_nr - 1); + + src.lines() + .enumerate() + .fold(0, |acc, (i, line)| match i.cmp(&line_nr) { + std::cmp::Ordering::Less => acc + line.len() + 1, + std::cmp::Ordering::Equal => acc + col_nr, + std::cmp::Ordering::Greater => acc, + }) +} diff --git a/crates/app/src/main.rs b/crates/app/src/main.rs index 6fec037..491e8b4 100644 --- a/crates/app/src/main.rs +++ b/crates/app/src/main.rs @@ -4,157 +4,10 @@ use welcome_msg::print_startup_msg; use crate::config::Configs; -mod cli { - use std::path::PathBuf; - - use clap::Parser; - - #[derive(Parser)] - pub(crate) struct Args { - /// Read this config file. - #[arg(short, long)] - pub config_file: Option, - #[arg(long, env = "NO_STARTUP_MESSAGE", default_value = "false")] - pub no_startup_message: bool, - } -} - -mod config { - use std::{ - fs, - path::{Path, PathBuf}, - process, - }; - - use serde::{Deserialize, Serialize}; - - use crate::error_reporting::{report_serde_json_err, report_serde_ron_err}; - - #[derive(Debug, Serialize, Deserialize)] - pub struct Configs { - #[serde(default = "default_example_value")] - pub example_value: i32, - #[serde(default = "default_no_startup_msg")] - pub no_startup_message: bool, - } - - /// what the fuck serde why do i need this - fn default_example_value() -> i32 { - 43 - } - fn default_no_startup_msg() -> bool { - false - } - - impl Configs { - pub fn read(custom_path: Option) -> Self { - use owo_colors::OwoColorize; - let p = match custom_path { - Some(p) => p, - None => { - let config_path = dirs::config_dir().expect("config dir should exist"); - - let ron_path = config_path.with_file_name("config.ron"); - let json_path = config_path.with_file_name("config.json"); - - if Path::new(&ron_path).exists() { - ron_path - } else if Path::new(&json_path).exists() { - json_path - } else { - eprintln!("{}: couldn't find config file", "Fatal error".red()); - process::exit(1) - } - } - }; - - match p.extension().map(|v| v.to_str().unwrap()) { - Some("ron") => Self::read_json(&fs::read_to_string(p).unwrap()), - Some("json") => Self::read_ron(&fs::read_to_string(p).unwrap()), - None | Some(_) => { - eprintln!( - "{}: couldn't determine config file type", - "Fatal error".red() - ); - process::exit(1) - } - } - } - pub fn read_json(config_text: &str) -> Configs { - match serde_json::from_str(config_text) { - Ok(c) => c, - Err(e) => report_serde_json_err(config_text, e), - } - } - - pub fn read_ron(config_text: &str) -> Configs { - match ron::from_str(config_text) { - Ok(c) => c, - Err(e) => report_serde_ron_err(config_text, e), - } - } - } -} - -mod error_reporting { - use std::process; - - use ron::error::Position; - - pub fn report_serde_json_err(src: &str, err: serde_json::Error) -> ! { - report_serde_err(src, err.line(), err.column(), err.to_string()) - } - - pub fn report_serde_ron_err(src: &str, err: ron::error::SpannedError) -> ! { - let Position { line, col } = err.position; - report_serde_err(src, line, col, err.to_string()) - } - - pub fn report_serde_err(src: &str, line: usize, col: usize, msg: String) -> ! { - use ariadne::{Label, Report, Source}; - let offset = try_reconstruct_loc(src, line, col); - - Report::build(ariadne::ReportKind::Error, "test", offset) - .with_label( - Label::new(("test", offset..offset)).with_message("Something went wrong here!"), - ) - .with_message(msg) - .with_note( - "We'd like to give better errors, but serde errors are horrible to work with...", - ) - .finish() - .print(("test", Source::from(src))) - .unwrap(); - process::exit(1); - } - fn try_reconstruct_loc(src: &str, line_nr: usize, col_nr: usize) -> usize { - let (line_nr, col_nr) = (line_nr - 1, col_nr - 1); - - src.lines() - .enumerate() - .fold(0, |acc, (i, line)| match i.cmp(&line_nr) { - std::cmp::Ordering::Less => acc + line.len() + 1, - std::cmp::Ordering::Equal => acc + col_nr, - std::cmp::Ordering::Greater => acc, - }) - } -} - -mod welcome_msg { - use time::{Month, OffsetDateTime}; - - pub fn print_startup_msg() { - // now or fallback to utc - let now = OffsetDateTime::now_local().unwrap_or_else(|_| OffsetDateTime::now_utc()); - - if now.month() == Month::June { - println!("Hello, thanks for using iOwO and happy pride month!"); - println!("Why pride month is important in {}", now.year()); - } else { - println!("Hello, thanks for using iOwO! :3"); - } - } -} +mod cli; +mod config; +mod error_reporting; +mod welcome_msg; fn main() { let args = Args::parse(); diff --git a/crates/app/src/welcome_msg.rs b/crates/app/src/welcome_msg.rs new file mode 100644 index 0000000..c03c543 --- /dev/null +++ b/crates/app/src/welcome_msg.rs @@ -0,0 +1,13 @@ +use time::{Month, OffsetDateTime}; + +pub fn print_startup_msg() { + // now or fallback to utc + let now = OffsetDateTime::now_local().unwrap_or_else(|_| OffsetDateTime::now_utc()); + + if now.month() == Month::June { + println!("Hello, thanks for using iOwO and happy pride month!"); + println!("Why pride month is important in {}", now.year()); + } else { + println!("Hello, thanks for using iOwO! :3"); + } +}