From 1cf4cf2394967f1045beff2c4e006bea3ad223f2 Mon Sep 17 00:00:00 2001 From: Sergio <77530549+sergi0g@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:28:32 +0300 Subject: [PATCH] Switch back to json --- Cargo.lock | 19 +++++++------------ Cargo.toml | 8 +++----- src/formatting.rs | 6 +++--- src/main.rs | 8 ++++---- src/registry.rs | 11 +++-------- src/server.rs | 27 ++++++++++++++------------- src/utils.rs | 40 +++++++++++++--------------------------- 7 files changed, 47 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 21d29c7..3632556 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,15 +355,13 @@ dependencies = [ "bollard", "chrono", "clap", - "home", "http-auth", "indicatif", + "json", "liquid", "once_cell", "rayon", "regex", - "serde", - "serde_json", "termsize", "tokio", "ureq", @@ -557,15 +555,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - [[package]] name = "http" version = "1.1.0" @@ -803,6 +792,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + [[package]] name = "kstring" version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index c4a4b51..7dc4092 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,6 @@ clap = { version = "4.5.7", features = ["derive"] } indicatif = { version = "0.17.8", optional = true } tokio = {version = "1.38.0", features = ["rt", "rt-multi-thread", "macros"]} ureq = { version = "2.9.7", features = ["tls"] } -serde_json = "1.0" rayon = "1.10.0" xitca-web = { version = "0.5.0", optional = true, features = ["logger"] } liquid = { version = "0.26.6", optional = true } @@ -17,13 +16,12 @@ once_cell = "1.19.0" http-auth = { version = "0.1.9", features = [] } termsize = { version = "0.1.8", optional = true } regex = "1.10.5" -chrono = { version = "0.4.38", default-features = false, features = ["std", "alloc", "clock"] } -home = "0.5.9" -serde = "1.0.204" +chrono = { version = "0.4.38", default-features = false, features = ["std", "alloc", "clock"], optional = true } +json = "0.12.4" [features] default = ["server", "cli"] -server = ["dep:xitca-web", "dep:liquid"] +server = ["dep:xitca-web", "dep:liquid", "dep:chrono"] cli = ["dep:indicatif", "dep:termsize"] [profile.release] diff --git a/src/formatting.rs b/src/formatting.rs index 411b777..e5c9149 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -1,7 +1,7 @@ use std::time::Duration; use indicatif::{ProgressBar, ProgressStyle}; -use serde_json::json; +use json::object; use crate::utils::{sort_update_vec, to_json}; @@ -40,7 +40,7 @@ pub fn print_updates(updates: &[(String, Option)], icons: &bool) { } pub fn print_raw_updates(updates: &[(String, Option)]) { - println!("{}", serde_json::to_string(&to_json(updates)).unwrap()); + println!("{}", json::stringify(to_json(updates))); } pub fn print_update(name: &str, has_update: &Option) { @@ -58,7 +58,7 @@ pub fn print_update(name: &str, has_update: &Option) { } pub fn print_raw_update(name: &str, has_update: &Option) { - let result = json!({"images": {name: has_update}}); + let result = object! {images: {[name]: *has_update}} ; println!("{}", result); } diff --git a/src/main.rs b/src/main.rs index 2ac37fb..4cbb5e2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ -use check::{get_all_updates, get_update}; use clap::{Parser, Subcommand}; #[cfg(feature = "cli")] use formatting::{print_raw_update, print_raw_updates, print_update, print_updates, Spinner}; #[cfg(feature = "cli")] +use check::{get_all_updates, get_update}; #[cfg(feature = "server")] use server::serve; use std::path::PathBuf; @@ -10,13 +10,13 @@ use utils::load_config; pub mod check; pub mod docker; -#[cfg(feature = "cli")] -pub mod formatting; pub mod image; pub mod registry; +pub mod utils; +#[cfg(feature = "cli")] +pub mod formatting; #[cfg(feature = "server")] pub mod server; -pub mod utils; #[derive(Parser)] #[command(version, about, long_about = None)] diff --git a/src/registry.rs b/src/registry.rs index 0d6caa9..ffa659e 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -1,7 +1,7 @@ use std::sync::Mutex; +use json::JsonValue; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; -use serde_json::Value; use ureq::Error; use http_auth::parse_challenges; @@ -95,18 +95,13 @@ pub fn get_token(images: Vec<&Image>, auth_url: &str) -> String { error!("Token request failed!\n{}", e) } }; - let parsed_token_response: Value = match serde_json::from_str(&raw_response) { + let parsed_token_response: JsonValue = match json::parse(&raw_response) { Ok(parsed) => parsed, Err(e) => { error!("Failed to parse server response\n{}", e) } }; - parsed_token_response - .get("token") - .unwrap() - .as_str() - .unwrap() - .to_string() + parsed_token_response["token"].to_string() } fn parse_www_authenticate(www_auth: &str) -> String { diff --git a/src/server.rs b/src/server.rs index abb442c..3044df0 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,6 +1,7 @@ -use std::{collections::HashMap, sync::Arc}; +use std::sync::Arc; use chrono::Local; +use json::JsonValue; use liquid::{object, Object}; use tokio::sync::Mutex; use xitca_web::{ @@ -15,7 +16,7 @@ use xitca_web::{ use crate::{ check::get_all_updates, error, - utils::{sort_update_vec, to_json, Config, JsonData}, + utils::{sort_update_vec, to_json}, }; const RAW_TEMPLATE: &str = include_str!("static/template.liquid"); @@ -24,7 +25,7 @@ const FAVICON_ICO: &[u8] = include_bytes!("static/favicon.ico"); const FAVICON_SVG: &[u8] = include_bytes!("static/favicon.svg"); const APPLE_TOUCH_ICON: &[u8] = include_bytes!("static/apple-touch-icon.png"); -pub async fn serve(port: &u16, socket: Option, config: Config) -> std::io::Result<()> { +pub async fn serve(port: &u16, socket: Option, config: JsonValue) -> std::io::Result<()> { let mut data = ServerData::new(socket, config).await; data.refresh().await; App::new() @@ -48,7 +49,7 @@ async fn home(data: StateRef<'_, Arc>>) -> WebResponse { async fn json(data: StateRef<'_, Arc>>) -> WebResponse { WebResponse::new(ResponseBody::from( - serde_json::to_string(&data.lock().await.json).unwrap(), + json::stringify(data.lock().await.json.clone()) )) } @@ -72,19 +73,19 @@ async fn apple_touch_icon() -> WebResponse { struct ServerData { template: String, raw_updates: Vec<(String, Option)>, - json: JsonData, + json: JsonValue, socket: Option, - config: Config, + config: JsonValue, } impl ServerData { - async fn new(socket: Option, config: Config) -> Self { + async fn new(socket: Option, config: JsonValue) -> Self { let mut s = Self { socket, template: String::new(), - json: JsonData { - metrics: HashMap::new(), - images: HashMap::new(), + json: json::object! { + metrics: json::object! {}, + images: json::object! {}, }, raw_updates: Vec::new(), config, @@ -110,8 +111,8 @@ impl ServerData { .collect::>(); self.json = to_json(&self.raw_updates); let last_updated = Local::now().format("%Y-%m-%d %H:%M:%S"); - let theme = match &self.config.theme { - Some(t) => match t.as_str() { + let theme = match &self.config["theme"].as_str() { + Some(t) => match *t { "default" => "neutral", "blue" => "gray", _ => error!( @@ -122,7 +123,7 @@ impl ServerData { None => "neutral", }; let globals = object!({ - "metrics": [{"name": "Monitored images", "value": self.json.metrics.get("monitored_images")}, {"name": "Up to date", "value": self.json.metrics.get("up_to_date")}, {"name": "Updates available", "value": self.json.metrics.get("update_available")}, {"name": "Unknown", "value": self.json.metrics.get("unknown")}], + "metrics": [{"name": "Monitored images", "value": self.json["metrics"]["monitored_images"].as_usize()}, {"name": "Up to date", "value": self.json["metrics"]["up_to_date"].as_usize()}, {"name": "Updates available", "value": self.json["metrics"]["update_available"].as_usize()}, {"name": "Unknown", "value": self.json["metrics"]["unknown"].as_usize()}], "images": images, "style": STYLE, "last_updated": last_updated.to_string(), diff --git a/src/utils.rs b/src/utils.rs index 82e5a8e..94f8cbd 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,8 +1,8 @@ -use std::{collections::HashMap, path::PathBuf}; +use std::path::PathBuf; +use json::{object, JsonValue}; use once_cell::sync::Lazy; use regex::Regex; -use serde::{Deserialize, Serialize}; /// This macro is an alternative to panic. It prints the message you give it and exits the process with code 1, without printing a stack trace. Useful for when the program has to exit due to a user error or something unexpected which is unrelated to the program (e.g. a failed web request) #[macro_export] @@ -87,7 +87,7 @@ pub fn sort_update_vec(updates: &[(String, Option)]) -> Vec<(String, Optio } /// Tries to load the config from the path provided and perform basic validation -pub fn load_config(config_path: Option) -> Config { +pub fn load_config(config_path: Option) -> JsonValue { let raw_config = match &config_path { Some(path) => std::fs::read_to_string(path), None => Ok(String::from("{\"theme\":\"default\"}")), @@ -98,25 +98,19 @@ pub fn load_config(config_path: Option) -> Config { &config_path.unwrap().to_str().unwrap() ) }; - match serde_json::from_str(&raw_config.unwrap()) { + match json::parse(&raw_config.unwrap()) { Ok(v) => v, Err(e) => panic!("Failed to parse config!\n{}", e), } } -#[derive(Deserialize)] -pub struct Config { - pub authentication: Option>, - pub theme: Option, -} - -pub fn to_json(updates: &[(String, Option)]) -> JsonData { - let mut json_data: JsonData = JsonData { - metrics: HashMap::new(), - images: HashMap::new(), +pub fn to_json(updates: &[(String, Option)]) -> JsonValue { + let mut json_data: JsonValue = object! { + metrics: object! {}, + images: object! {} }; updates.iter().for_each(|(image, has_update)| { - let _ = json_data.images.insert(image.clone(), *has_update); + let _ = json_data["images"].insert(image, *has_update); }); let up_to_date = updates .iter() @@ -133,17 +127,9 @@ pub fn to_json(updates: &[(String, Option)]) -> JsonData { .filter(|&(_, value)| value.is_none()) .collect::)>>() .len(); - let _ = json_data.metrics.insert("monitored_images", updates.len()); - let _ = json_data.metrics.insert("up_to_date", up_to_date); - let _ = json_data - .metrics - .insert("update_available", update_available); - let _ = json_data.metrics.insert("unknown", unknown); + let _ = json_data["metrics"].insert("monitored_images", updates.len()); + let _ = json_data["metrics"].insert("up_to_date", up_to_date); + let _ = json_data["metrics"].insert("update_available", update_available); + let _ = json_data["metrics"].insert("unknown", unknown); json_data } - -#[derive(Serialize)] -pub struct JsonData { - pub metrics: HashMap<&'static str, usize>, - pub images: HashMap>, -}