From c2fe292b2d9e261f7b56e884166a05db4c6d5e44 Mon Sep 17 00:00:00 2001 From: Mossfet Date: Fri, 30 Jun 2023 11:47:46 +0100 Subject: [PATCH 1/5] Prepped code for names being defined at runtime in rocket() --- Cargo.lock | 1 + Cargo.toml | 3 +++ src/links.rs | 20 +++++++++++--------- src/main.rs | 8 ++++++++ src/names.rs | 41 +++++++++++++++++++++++++++++++++++++++++ src/routes.rs | 21 +++++++++++++-------- 6 files changed, 77 insertions(+), 17 deletions(-) create mode 100644 src/names.rs diff --git a/Cargo.lock b/Cargo.lock index 1d6a58a..449c625 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -663,6 +663,7 @@ dependencies = [ "askama_rocket", "rocket", "rust-embed", + "serde_json", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a54a5aa..72a25cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,9 @@ features = ["json"] version = "6.7.0" features = ["debug-embed"] +[dependencies.serde_json] +version = "1.0" + [dependencies.askama_rocket] git = "https://github.com/djc/askama.git" package = "askama_rocket" diff --git a/src/links.rs b/src/links.rs index eab9c10..d4e6a05 100644 --- a/src/links.rs +++ b/src/links.rs @@ -1,18 +1,20 @@ -static NAMES: [&str; 3] = ["mossfet.xyz", "fries.gay", "ta-kev.digital"]; +use crate::names::Site; -pub fn previous_url(source_url: &String) -> Option { - match NAMES.iter().position(|&r| r == source_url) { - Some(index) if index == 0 => Some(NAMES[NAMES.len() - 1].to_string()), - Some(index) => Some(NAMES[index - 1].to_string()), +pub fn previous_url(source_url: &String, names: &Vec) -> Option { + match names.iter().position(|r| r.url() == source_url) { + Some(index) if index == 0 => Some(names[names.len() - 1].url().to_string()), + Some(index) => Some(names[index - 1].url().to_string()), None => None, } } -pub fn next_url(source_url: &String) -> Option { +pub fn next_url(source_url: &String, names: &Vec) -> Option { // this is gay - match NAMES.iter().position(|&r| r == source_url) { - Some(index) if index == NAMES.len() - 1 => Some(NAMES[0].to_string()), - Some(index) => Some(NAMES[index + 1].to_string()), + match names.iter().position(|r| r.url() == source_url) { + Some(index) if index == names.len() - 1 => Some(names[0].url().to_string()), + Some(index) => Some(names[index + 1].url().to_string()), None => None, } } + +// TODO: previous_name, next_name diff --git a/src/main.rs b/src/main.rs index 6cb7fda..7e7c302 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,10 +4,18 @@ extern crate rocket; mod assets; mod links; mod routes; +mod names; + +use names::Site; #[launch] fn rocket() -> _ { + let names = vec![ + Site::new("mossfet.xyz", Some("Mossy's site")), + Site::new("fries.gay", Some("Fries's site")) + ]; rocket::build() + .manage(names) .mount( "/", routes![routes::index, routes::previous, routes::next, routes::name], diff --git a/src/names.rs b/src/names.rs new file mode 100644 index 0000000..0ce6c83 --- /dev/null +++ b/src/names.rs @@ -0,0 +1,41 @@ +use std::fs::File; +use std::io::{BufReader, Read}; + +pub enum NamesError { + FileAccessError, + ParseError, +} + +pub fn load_names(names_file: File) -> Result, NamesError> { + let mut buf_reader = BufReader::new(names_file); + let mut contents = String::new(); + match buf_reader.read_to_string(&mut contents) { + Ok(_) => {}, + Err(_) => {return Err(NamesError::FileAccessError)}, + } + println!("{}", contents); + Err(NamesError::ParseError) +} + +pub struct Site { + url: String, + name: Option, +} + +impl Site { + pub fn new(url: &str, name: Option<&str>) -> Self { + Site { + url: url.to_string(), + name: name.map(str::to_string), + } + } + pub fn url(&self) -> &String { + &self.url + } + pub fn name(&self) -> Option<&String> { + match &self.name { + Some(name) => Some(&name), + None => None + } + } +} diff --git a/src/routes.rs b/src/routes.rs index d263734..e0eab00 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -1,8 +1,11 @@ -use crate::{links::{next_url, previous_url}, assets::ErrorTemplate}; +use crate::{links::{next_url, previous_url}, assets::ErrorTemplate, names::Site}; +static NAMES: [&str; 3] = ["mossfet.xyz", "fries.gay", "ta-kev.digital"]; + use rocket::{ http::Status, response::Redirect, serde::{json::Json, Serialize}, + State, }; const NOT_FOUND_ERROR: ErrorTemplate = ErrorTemplate { @@ -23,25 +26,27 @@ pub fn index() -> &'static str { } #[get("/previous?")] -pub fn previous(source_url: String) -> Result { - match previous_url(&source_url) { +pub fn previous(source_url: String, names: &State>) -> Result { + let names = names.inner(); + match previous_url(&source_url, names) { Some(url) => Ok(Redirect::to(format!("https://{}", url))), None => Err(Status::NotFound), } } #[get("/next?")] -pub fn next(source_url: String) -> Result { - match next_url(&source_url) { +pub fn next(source_url: String, names: &State>) -> Result { + let names = names.inner(); + match next_url(&source_url, names) { Some(url) => Ok(Redirect::to(format!("https://{}", url))), None => Err(Status::NotFound), } } #[get("/name?")] -pub fn name(source_url: String) -> Result, Status> { - let previous_site_name = previous_url(&source_url); - let next_site_name = next_url(&source_url); +pub fn name(source_url: String, names: &State>) -> Result, Status> { + let previous_site_name = previous_url(&source_url, names); + let next_site_name = next_url(&source_url, names); if previous_site_name.is_none() && next_site_name.is_none() { return Err(Status::NotFound); From 1667e14d647bc74ade3e703805e499446decf42b Mon Sep 17 00:00:00 2001 From: Mossfet Date: Fri, 30 Jun 2023 17:47:25 +0100 Subject: [PATCH 2/5] Initial json parsing --- .gitignore | 1 + src/main.rs | 6 ++---- src/names.rs | 30 +++++++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index ea8c4bf..a2a1b8a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +names.json diff --git a/src/main.rs b/src/main.rs index 7e7c302..5d9e7c9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,10 +10,8 @@ use names::Site; #[launch] fn rocket() -> _ { - let names = vec![ - Site::new("mossfet.xyz", Some("Mossy's site")), - Site::new("fries.gay", Some("Fries's site")) - ]; + let names_file = std::fs::File::open("names.json").unwrap(); + let names = names::load_names(names_file).unwrap(); rocket::build() .manage(names) .mount( diff --git a/src/names.rs b/src/names.rs index 0ce6c83..fbc39b4 100644 --- a/src/names.rs +++ b/src/names.rs @@ -1,6 +1,8 @@ use std::fs::File; use std::io::{BufReader, Read}; +use serde_json::{Map, Value}; +#[derive(Debug)] pub enum NamesError { FileAccessError, ParseError, @@ -8,13 +10,39 @@ pub enum NamesError { pub fn load_names(names_file: File) -> Result, NamesError> { let mut buf_reader = BufReader::new(names_file); + let mut output: Vec = vec![]; let mut contents = String::new(); match buf_reader.read_to_string(&mut contents) { Ok(_) => {}, Err(_) => {return Err(NamesError::FileAccessError)}, } + println!("{}", contents); - Err(NamesError::ParseError) + + match serde_json::from_str(&contents) { + Ok(Value::Array(sites_array)) => { + for i in sites_array { + match i { + Value::Object(site) => { + let url = site.get("url"); + let name = site.get("name"); + match (url, name) { + (Some(Value::String(url)), Some(Value::String(name))) => { + output.push(Site::new(url, Some(name))); + }, + (Some(Value::String(url)), None) => { + output.push(Site::new(url, None)); + }, + _ => {return Err(NamesError::ParseError)}, + }; + } + _ => {return Err(NamesError::ParseError)} + } + } + } + _ => {return Err(NamesError::ParseError)} + } + Ok(output) } pub struct Site { From c481999c55fde15935ffec6c6c90ab273a74dd6e Mon Sep 17 00:00:00 2001 From: Fries Date: Fri, 30 Jun 2023 21:43:18 -0700 Subject: [PATCH 3/5] add a work in progress cli and fix bugs i'm making a cli that lets you add stuff to the names.json file and read data from it and i moved stuff that can be shared between them like the Site struct to a shared crate thats in workspace, like the cli crate. i also switched to using typed json parsing which works well. --- Cargo.lock | 134 +++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 13 ++++- cli/Cargo.toml | 19 ++++++ cli/src/arguments.rs | 30 ++++++++++ cli/src/commands.rs | 18 ++++++ cli/src/main.rs | 14 +++++ shared/Cargo.toml | 11 ++++ shared/src/lib.rs | 1 + shared/src/names.rs | 20 +++++++ src/links.rs | 14 ++--- src/main.rs | 6 +- src/names.rs | 83 ++++++--------------------- src/routes.rs | 3 +- 13 files changed, 288 insertions(+), 78 deletions(-) create mode 100644 cli/Cargo.toml create mode 100644 cli/src/arguments.rs create mode 100644 cli/src/commands.rs create mode 100644 cli/src/main.rs create mode 100644 shared/Cargo.toml create mode 100644 shared/src/lib.rs create mode 100644 shared/src/names.rs diff --git a/Cargo.lock b/Cargo.lock index 449c625..e7b8a18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,55 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys", +] + [[package]] name = "askama" version = "0.12.0" @@ -172,6 +221,63 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "4.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384e169cc618c613d5e3ca6404dda77a8685a63e08660dcc64abaf7da7cb0c7a" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef137bbe35aab78bdb468ccfba75a5f4d8321ae011d34063770780545176af2d" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" + +[[package]] +name = "cli" +version = "0.1.0" +dependencies = [ + "clap", + "serde", + "serde_json", + "shared", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "cookie" version = "0.17.0" @@ -439,6 +545,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.2.6" @@ -663,7 +775,9 @@ dependencies = [ "askama_rocket", "rocket", "rust-embed", + "serde", "serde_json", + "shared", ] [[package]] @@ -1207,6 +1321,14 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shared" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -1265,6 +1387,12 @@ dependencies = [ "loom", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "2.0.22" @@ -1534,6 +1662,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "valuable" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 72a25cd..005d5e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = ["cli", "shared"] + [package] name = "meowy-webring" version = "0.1.0" @@ -11,9 +14,12 @@ default_features = false features = ["json"] [dependencies.rust-embed] -version = "6.7.0" +version = "6" features = ["debug-embed"] +[dependencies.serde] +version = "1.0" + [dependencies.serde_json] version = "1.0" @@ -27,5 +33,8 @@ git = "https://github.com/djc/askama.git" package = "askama" rev = "b9e51601560398766eac445517fb17c35090a952" version = "0.12" -default-features = true +default-features = true features = ["with-rocket", "mime", "mime_guess"] + +[dependencies.shared] +path = "./shared" diff --git a/cli/Cargo.toml b/cli/Cargo.toml new file mode 100644 index 0000000..a79600c --- /dev/null +++ b/cli/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "cli" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0" +serde_json = "1.0" + +[dependencies.clap] +version = "4" +features = ["derive"] + +[dependencies.shared] +path = "../shared" + +[[bin]] +name = "meowy-cli" +path = "src/main.rs" diff --git a/cli/src/arguments.rs b/cli/src/arguments.rs new file mode 100644 index 0000000..7db619e --- /dev/null +++ b/cli/src/arguments.rs @@ -0,0 +1,30 @@ +use clap::{Parser, command, Subcommand, arg, Args}; + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +pub(crate) struct Arguments { + #[command(subcommand)] + pub(crate) command: Commands +} + + +#[derive(Subcommand, Debug)] +pub(crate) enum Commands { + #[command(about = "print the current webring sites and their names")] + Print { + #[arg(help = "the path to the names.json file")] + path: String, + #[command(flatten)] + group: Group + } + +} + +#[derive(Args, Debug)] +#[group(required = false)] +pub struct Group { + #[arg(long, short, action = clap::ArgAction::SetTrue, conflicts_with = "name", help = "print the url only")] + pub(crate) url: bool, + #[arg(long, short, action = clap::ArgAction::SetTrue, conflicts_with = "url", help = "print the name only")] + pub(crate) name: bool +} diff --git a/cli/src/commands.rs b/cli/src/commands.rs new file mode 100644 index 0000000..e5d80ee --- /dev/null +++ b/cli/src/commands.rs @@ -0,0 +1,18 @@ +use crate::arguments::Group; + +pub(crate) fn print(path: &String, group: &Group) { + let names = std::fs::read_to_string(path).unwrap(); + let parsed_names = shared::names::load_names(names).unwrap(); + + for site in parsed_names { + if group.name { + println!("{}", site.name.unwrap_or_default()); + continue; + } + if group.url { + println!("{}", site.url); + continue; + } + println!("{:?}", site); + } +} diff --git a/cli/src/main.rs b/cli/src/main.rs new file mode 100644 index 0000000..482b758 --- /dev/null +++ b/cli/src/main.rs @@ -0,0 +1,14 @@ +use arguments::{Arguments, Commands}; +use clap::Parser; +use commands::print; + +mod arguments; +mod commands; + +fn main() { + let args = Arguments::parse(); + + match &args.command { + Commands::Print { path, group } => print(path, group) + } +} diff --git a/shared/Cargo.toml b/shared/Cargo.toml new file mode 100644 index 0000000..aa08613 --- /dev/null +++ b/shared/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "shared" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde_json = "1.0" + +[dependencies.serde] +version = "1.0" +features = ["derive"] diff --git a/shared/src/lib.rs b/shared/src/lib.rs new file mode 100644 index 0000000..d2f54b1 --- /dev/null +++ b/shared/src/lib.rs @@ -0,0 +1 @@ +pub mod names; diff --git a/shared/src/names.rs b/shared/src/names.rs new file mode 100644 index 0000000..112862e --- /dev/null +++ b/shared/src/names.rs @@ -0,0 +1,20 @@ +use serde::Deserialize; + +#[derive(Deserialize, Debug)] +pub struct Site { + pub url: String, + pub name: Option, +} + +#[derive(Debug)] +pub enum NamesError { + FileAccessError, + ParseError, +} + +pub fn load_names(names: String) -> Result, NamesError> { + match serde_json::from_str::>(&names) { + Ok(content) => Ok(content), + Err(_) => Err(NamesError::ParseError) + } +} diff --git a/src/links.rs b/src/links.rs index d4e6a05..fb742a3 100644 --- a/src/links.rs +++ b/src/links.rs @@ -1,18 +1,18 @@ -use crate::names::Site; +use shared::names::Site; pub fn previous_url(source_url: &String, names: &Vec) -> Option { - match names.iter().position(|r| r.url() == source_url) { - Some(index) if index == 0 => Some(names[names.len() - 1].url().to_string()), - Some(index) => Some(names[index - 1].url().to_string()), + match names.iter().position(|r| &r.url == source_url) { + Some(index) if index == 0 => Some(names[names.len() - 1].url.to_string()), + Some(index) => Some(names[index - 1].url.to_string()), None => None, } } pub fn next_url(source_url: &String, names: &Vec) -> Option { // this is gay - match names.iter().position(|r| r.url() == source_url) { - Some(index) if index == names.len() - 1 => Some(names[0].url().to_string()), - Some(index) => Some(names[index + 1].url().to_string()), + match names.iter().position(|r| &r.url == source_url) { + Some(index) if index == names.len() - 1 => Some(names[0].url.to_string()), + Some(index) => Some(names[index + 1].url.to_string()), None => None, } } diff --git a/src/main.rs b/src/main.rs index 5d9e7c9..2647299 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,12 +6,10 @@ mod links; mod routes; mod names; -use names::Site; - #[launch] fn rocket() -> _ { - let names_file = std::fs::File::open("names.json").unwrap(); - let names = names::load_names(names_file).unwrap(); + let names_file = std::fs::read_to_string("names.json").unwrap(); + let names = shared::names::load_names(names_file).unwrap(); rocket::build() .manage(names) .mount( diff --git a/src/names.rs b/src/names.rs index fbc39b4..ab58c1c 100644 --- a/src/names.rs +++ b/src/names.rs @@ -1,69 +1,24 @@ +use serde::{Deserialize, Serialize}; +use serde_json::{Map, Value}; use std::fs::File; use std::io::{BufReader, Read}; -use serde_json::{Map, Value}; -#[derive(Debug)] -pub enum NamesError { - FileAccessError, - ParseError, -} -pub fn load_names(names_file: File) -> Result, NamesError> { - let mut buf_reader = BufReader::new(names_file); - let mut output: Vec = vec![]; - let mut contents = String::new(); - match buf_reader.read_to_string(&mut contents) { - Ok(_) => {}, - Err(_) => {return Err(NamesError::FileAccessError)}, - } - println!("{}", contents); - - match serde_json::from_str(&contents) { - Ok(Value::Array(sites_array)) => { - for i in sites_array { - match i { - Value::Object(site) => { - let url = site.get("url"); - let name = site.get("name"); - match (url, name) { - (Some(Value::String(url)), Some(Value::String(name))) => { - output.push(Site::new(url, Some(name))); - }, - (Some(Value::String(url)), None) => { - output.push(Site::new(url, None)); - }, - _ => {return Err(NamesError::ParseError)}, - }; - } - _ => {return Err(NamesError::ParseError)} - } - } - } - _ => {return Err(NamesError::ParseError)} - } - Ok(output) -} - -pub struct Site { - url: String, - name: Option, -} - -impl Site { - pub fn new(url: &str, name: Option<&str>) -> Self { - Site { - url: url.to_string(), - name: name.map(str::to_string), - } - } - pub fn url(&self) -> &String { - &self.url - } - pub fn name(&self) -> Option<&String> { - match &self.name { - Some(name) => Some(&name), - None => None - } - } -} +// impl Site { +// pub fn new(url: &str, name: Option<&str>) -> Self { +// Site { +// url: url.to_string(), +// name: name.map(str::to_string), +// } +// } +// pub fn url(&self) -> &String { +// &self.url +// } +// pub fn name(&self) -> Option<&String> { +// match &self.name { +// Some(name) => Some(&name), +// None => None, +// } +// } +// } diff --git a/src/routes.rs b/src/routes.rs index e0eab00..7b600cb 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -1,4 +1,4 @@ -use crate::{links::{next_url, previous_url}, assets::ErrorTemplate, names::Site}; +use crate::{links::{next_url, previous_url}, assets::ErrorTemplate}; static NAMES: [&str; 3] = ["mossfet.xyz", "fries.gay", "ta-kev.digital"]; use rocket::{ @@ -7,6 +7,7 @@ use rocket::{ serde::{json::Json, Serialize}, State, }; +use shared::names::Site; const NOT_FOUND_ERROR: ErrorTemplate = ErrorTemplate { error: "Not Found", From c729d2115bc5575257df2327094f4592c9ba4815 Mon Sep 17 00:00:00 2001 From: Fries Date: Fri, 30 Jun 2023 22:11:44 -0700 Subject: [PATCH 4/5] add a add command to the cli this command can add sites to the names.json file --- cli/src/arguments.rs | 44 ++++++++++++++++++++++++++++++++++---------- cli/src/commands.rs | 22 ++++++++++++++++++++-- cli/src/main.rs | 6 ++++-- shared/src/names.rs | 6 +++--- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/cli/src/arguments.rs b/cli/src/arguments.rs index 7db619e..413b6f5 100644 --- a/cli/src/arguments.rs +++ b/cli/src/arguments.rs @@ -1,30 +1,54 @@ -use clap::{Parser, command, Subcommand, arg, Args}; +use clap::{arg, command, Args, Parser, Subcommand}; #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] pub(crate) struct Arguments { + #[arg(help = "the path to the names.json file")] + pub(crate) path: String, #[command(subcommand)] - pub(crate) command: Commands + pub(crate) command: Commands, } - #[derive(Subcommand, Debug)] pub(crate) enum Commands { #[command(about = "print the current webring sites and their names")] Print { - #[arg(help = "the path to the names.json file")] - path: String, #[command(flatten)] - group: Group - } - + group: PrintGroup, + }, + #[command(about = "add a site to the webring")] + Add { + #[arg( + long, + short, + required = true, + help = "the url of the site you want to add. example: \"example.com\"." + )] + url: String, + #[arg( + long, + short, + required = false, + help = "the personal name of the site. this is not required." + )] + name: Option, + }, + Remove { + #[arg( + long, + short, + required = true, + help = "the url of the site you want to remove." + )] + url: String, + }, } #[derive(Args, Debug)] #[group(required = false)] -pub struct Group { +pub struct PrintGroup { #[arg(long, short, action = clap::ArgAction::SetTrue, conflicts_with = "name", help = "print the url only")] pub(crate) url: bool, #[arg(long, short, action = clap::ArgAction::SetTrue, conflicts_with = "url", help = "print the name only")] - pub(crate) name: bool + pub(crate) name: bool, } diff --git a/cli/src/commands.rs b/cli/src/commands.rs index e5d80ee..f21906c 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -1,6 +1,13 @@ -use crate::arguments::Group; +use shared::names::Site; -pub(crate) fn print(path: &String, group: &Group) { +use crate::arguments::PrintGroup; + +fn read_names(path: &String) -> Vec { + let names = std::fs::read_to_string(path).unwrap(); + shared::names::load_names(names).unwrap() +} + +pub(crate) fn print(path: &String, group: &PrintGroup) { let names = std::fs::read_to_string(path).unwrap(); let parsed_names = shared::names::load_names(names).unwrap(); @@ -16,3 +23,14 @@ pub(crate) fn print(path: &String, group: &Group) { println!("{:?}", site); } } + +pub(crate) fn add(path: &String, url: &String, name: &Option) { + let mut names = read_names(path); + let site = Site { + url: url.to_string(), + name: name.to_owned(), + }; + names.push(site); + let json = serde_json::to_string(&names).unwrap(); + std::fs::write(path, json).unwrap(); +} diff --git a/cli/src/main.rs b/cli/src/main.rs index 482b758..e6f330e 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,6 +1,6 @@ use arguments::{Arguments, Commands}; use clap::Parser; -use commands::print; +use commands::{add, print}; mod arguments; mod commands; @@ -9,6 +9,8 @@ fn main() { let args = Arguments::parse(); match &args.command { - Commands::Print { path, group } => print(path, group) + Commands::Print { group } => print(&args.path, &group), + Commands::Add { url, name } => add(&args.path, url, name), + Commands::Remove { url } => todo!(), } } diff --git a/shared/src/names.rs b/shared/src/names.rs index 112862e..cbf8e4f 100644 --- a/shared/src/names.rs +++ b/shared/src/names.rs @@ -1,6 +1,6 @@ -use serde::Deserialize; +use serde::{Deserialize, Serialize}; -#[derive(Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug)] pub struct Site { pub url: String, pub name: Option, @@ -15,6 +15,6 @@ pub enum NamesError { pub fn load_names(names: String) -> Result, NamesError> { match serde_json::from_str::>(&names) { Ok(content) => Ok(content), - Err(_) => Err(NamesError::ParseError) + Err(_) => Err(NamesError::ParseError), } } From 9411e4a09724768d9d4965cc52ecd79e5c8fb0a8 Mon Sep 17 00:00:00 2001 From: Fries Date: Fri, 30 Jun 2023 23:12:55 -0700 Subject: [PATCH 5/5] add a remove command and error handling to the cli --- Cargo.lock | 38 -------------------------------------- Cargo.toml | 4 ++-- cli/src/arguments.rs | 1 + cli/src/commands.rs | 40 +++++++++++++++++++++++++++++----------- cli/src/main.rs | 15 +++++++++------ shared/src/errors.rs | 16 ++++++++++++++++ shared/src/lib.rs | 1 + shared/src/names.rs | 15 +++++++-------- src/main.rs | 1 - src/names.rs | 24 ------------------------ src/routes.rs | 1 - 11 files changed, 65 insertions(+), 91 deletions(-) create mode 100644 shared/src/errors.rs delete mode 100644 src/names.rs diff --git a/Cargo.lock b/Cargo.lock index e7b8a18..d7d739a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,9 +73,6 @@ source = "git+https://github.com/djc/askama.git?rev=b9e51601560398766eac445517fb dependencies = [ "askama_derive", "askama_escape", - "humansize", - "num-traits", - "percent-encoding", ] [[package]] @@ -83,13 +80,11 @@ name = "askama_derive" version = "0.12.1" source = "git+https://github.com/djc/askama.git?rev=b9e51601560398766eac445517fb17c35090a952#b9e51601560398766eac445517fb17c35090a952" dependencies = [ - "basic-toml", "mime", "mime_guess", "nom", "proc-macro2", "quote", - "serde", "syn", ] @@ -167,15 +162,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "basic-toml" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1" -dependencies = [ - "serde", -] - [[package]] name = "binascii" version = "0.1.4" @@ -600,15 +586,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" -[[package]] -name = "humansize" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" -dependencies = [ - "libm", -] - [[package]] name = "hyper" version = "0.14.27" @@ -709,12 +686,6 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" -[[package]] -name = "libm" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" - [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -862,15 +833,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - [[package]] name = "num_cpus" version = "1.15.0" diff --git a/Cargo.toml b/Cargo.toml index 005d5e8..aa5abe7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,14 +27,14 @@ version = "1.0" git = "https://github.com/djc/askama.git" package = "askama_rocket" rev = "b9e51601560398766eac445517fb17c35090a952" +default-features = false [dependencies.askama] git = "https://github.com/djc/askama.git" package = "askama" rev = "b9e51601560398766eac445517fb17c35090a952" version = "0.12" -default-features = true -features = ["with-rocket", "mime", "mime_guess"] +default-features = false [dependencies.shared] path = "./shared" diff --git a/cli/src/arguments.rs b/cli/src/arguments.rs index 413b6f5..952da36 100644 --- a/cli/src/arguments.rs +++ b/cli/src/arguments.rs @@ -33,6 +33,7 @@ pub(crate) enum Commands { )] name: Option, }, + #[command(about = "remove a site from the webring")] Remove { #[arg( long, diff --git a/cli/src/commands.rs b/cli/src/commands.rs index f21906c..e2cdebb 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -1,17 +1,26 @@ -use shared::names::Site; +use shared::{ + errors::{Error, ErrorStatus}, + names::Site, +}; use crate::arguments::PrintGroup; -fn read_names(path: &String) -> Vec { - let names = std::fs::read_to_string(path).unwrap(); - shared::names::load_names(names).unwrap() +fn read_names(path: &String) -> Result, Error> { + match std::fs::read_to_string(path) { + Ok(names) => { + return shared::names::load_names(names); + } + Err(err) => Err(Error { + status: ErrorStatus::IOError, + data: err.to_string(), + }), + } } -pub(crate) fn print(path: &String, group: &PrintGroup) { - let names = std::fs::read_to_string(path).unwrap(); - let parsed_names = shared::names::load_names(names).unwrap(); +pub(crate) fn print(path: &String, group: &PrintGroup) -> Result<(), Error> { + let names = read_names(path)?; - for site in parsed_names { + Ok(for site in names { if group.name { println!("{}", site.name.unwrap_or_default()); continue; @@ -21,11 +30,11 @@ pub(crate) fn print(path: &String, group: &PrintGroup) { continue; } println!("{:?}", site); - } + }) } -pub(crate) fn add(path: &String, url: &String, name: &Option) { - let mut names = read_names(path); +pub(crate) fn add(path: &String, url: &String, name: &Option) -> Result<(), Error> { + let mut names = read_names(path)?; let site = Site { url: url.to_string(), name: name.to_owned(), @@ -33,4 +42,13 @@ pub(crate) fn add(path: &String, url: &String, name: &Option) { names.push(site); let json = serde_json::to_string(&names).unwrap(); std::fs::write(path, json).unwrap(); + Ok(()) +} + +pub(crate) fn remove(path: &String, url: &String) -> Result<(), Error> { + let mut names = read_names(path)?; + names.retain(|site| &site.url != url); + let json = serde_json::to_string(&names).unwrap(); + std::fs::write(path, json).unwrap(); + Ok(()) } diff --git a/cli/src/main.rs b/cli/src/main.rs index e6f330e..621e6b3 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,16 +1,19 @@ use arguments::{Arguments, Commands}; use clap::Parser; -use commands::{add, print}; +use commands::{add, print, remove}; +use shared::errors::Error; mod arguments; mod commands; -fn main() { +fn main() -> Result<(), Error> { let args = Arguments::parse(); match &args.command { - Commands::Print { group } => print(&args.path, &group), - Commands::Add { url, name } => add(&args.path, url, name), - Commands::Remove { url } => todo!(), - } + Commands::Print { group } => print(&args.path, &group)?, + Commands::Add { url, name } => add(&args.path, url, name)?, + Commands::Remove { url } => remove(&args.path, url)?, + }; + + Ok(()) } diff --git a/shared/src/errors.rs b/shared/src/errors.rs new file mode 100644 index 0000000..8a033d5 --- /dev/null +++ b/shared/src/errors.rs @@ -0,0 +1,16 @@ +#[derive(Debug)] +pub enum ErrorStatus { + IOError, + ParsingError +} + +pub struct Error { + pub status: ErrorStatus, + pub data: String +} + +impl core::fmt::Debug for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "A {:?} error has occured.\nDetails: {}", self.status, self.data) + } +} diff --git a/shared/src/lib.rs b/shared/src/lib.rs index d2f54b1..c986a43 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -1 +1,2 @@ pub mod names; +pub mod errors; diff --git a/shared/src/names.rs b/shared/src/names.rs index cbf8e4f..6408d6c 100644 --- a/shared/src/names.rs +++ b/shared/src/names.rs @@ -1,20 +1,19 @@ use serde::{Deserialize, Serialize}; +use crate::errors::{Error, ErrorStatus}; + #[derive(Serialize, Deserialize, Debug)] pub struct Site { pub url: String, pub name: Option, } -#[derive(Debug)] -pub enum NamesError { - FileAccessError, - ParseError, -} - -pub fn load_names(names: String) -> Result, NamesError> { +pub fn load_names(names: String) -> Result, Error> { match serde_json::from_str::>(&names) { Ok(content) => Ok(content), - Err(_) => Err(NamesError::ParseError), + Err(err) => Err(Error { + status: ErrorStatus::ParsingError, + data: err.to_string(), + }), } } diff --git a/src/main.rs b/src/main.rs index 2647299..ae43a88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,6 @@ extern crate rocket; mod assets; mod links; mod routes; -mod names; #[launch] fn rocket() -> _ { diff --git a/src/names.rs b/src/names.rs deleted file mode 100644 index ab58c1c..0000000 --- a/src/names.rs +++ /dev/null @@ -1,24 +0,0 @@ -use serde::{Deserialize, Serialize}; -use serde_json::{Map, Value}; -use std::fs::File; -use std::io::{BufReader, Read}; - - - -// impl Site { -// pub fn new(url: &str, name: Option<&str>) -> Self { -// Site { -// url: url.to_string(), -// name: name.map(str::to_string), -// } -// } -// pub fn url(&self) -> &String { -// &self.url -// } -// pub fn name(&self) -> Option<&String> { -// match &self.name { -// Some(name) => Some(&name), -// None => None, -// } -// } -// } diff --git a/src/routes.rs b/src/routes.rs index 7b600cb..576669b 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -1,5 +1,4 @@ use crate::{links::{next_url, previous_url}, assets::ErrorTemplate}; -static NAMES: [&str; 3] = ["mossfet.xyz", "fries.gay", "ta-kev.digital"]; use rocket::{ http::Status,