split up modules into subfiles
This commit is contained in:
parent
96208d13e5
commit
02180561cd
5 changed files with 140 additions and 151 deletions
12
crates/app/src/cli.rs
Normal file
12
crates/app/src/cli.rs
Normal file
|
@ -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<PathBuf>,
|
||||||
|
#[arg(long, env = "NO_STARTUP_MESSAGE", default_value = "false")]
|
||||||
|
pub no_startup_message: bool,
|
||||||
|
}
|
74
crates/app/src/config.rs
Normal file
74
crates/app/src/config.rs
Normal file
|
@ -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<PathBuf>) -> 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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
crates/app/src/error_reporting.rs
Normal file
37
crates/app/src/error_reporting.rs
Normal file
|
@ -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,
|
||||||
|
})
|
||||||
|
}
|
|
@ -4,157 +4,10 @@ use welcome_msg::print_startup_msg;
|
||||||
|
|
||||||
use crate::config::Configs;
|
use crate::config::Configs;
|
||||||
|
|
||||||
mod cli {
|
mod cli;
|
||||||
use std::path::PathBuf;
|
mod config;
|
||||||
|
mod error_reporting;
|
||||||
use clap::Parser;
|
mod welcome_msg;
|
||||||
|
|
||||||
#[derive(Parser)]
|
|
||||||
pub(crate) struct Args {
|
|
||||||
/// Read this config file.
|
|
||||||
#[arg(short, long)]
|
|
||||||
pub config_file: Option<PathBuf>,
|
|
||||||
#[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<PathBuf>) -> 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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
13
crates/app/src/welcome_msg.rs
Normal file
13
crates/app/src/welcome_msg.rs
Normal file
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue