From 75906abc47b218d76537e82d108c7ced87f0a7c4 Mon Sep 17 00:00:00 2001 From: fgirault Date: Tue, 16 Jul 2024 08:47:55 +0200 Subject: [PATCH] refactor: :recycle: Handle channel rendering in a separate module --- Cargo.toml | 5 +++-- README.md | 8 ++++++-- src/args.rs | 3 +++ src/channel_lib.rs | 4 ++-- src/json_lib.rs | 6 ++++-- src/main.rs | 45 ++++++++++----------------------------------- src/render.rs | 28 ++++++++++++++++++++++++++++ 7 files changed, 56 insertions(+), 43 deletions(-) create mode 100644 src/render.rs diff --git a/Cargo.toml b/Cargo.toml index 70ad08e..9f74fd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,13 +9,14 @@ authors = ["François Girault "] [dependencies] rss = "2.0" -url = "2.5.2" +# url = "2.5.2" json = "0.12.4" clap = { version = "4.5.9", features = ["derive"] } chrono = "0.4.38" env_logger = "0.11.3" log = "0.4.22" reqwest = { version = "0.12.5", features = ["blocking"] } -# regex = "1.10.5" # polodb_core = "4.4.1" +# serde = "1.0.204" +# regex = "1.10.5" diff --git a/README.md b/README.md index 4cd98d7..ec25af3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ rss2json converts rss xml feeds to a json format. ## About -This is my first Rust tutorial project, so surely not coded with all the best practices. +**This is my first Rust tutorial project**, so surely not coded with all the best practices, and clearly useless. Output format is a complete personnal choice, inspired by some formats I've seen when using other's api. @@ -12,12 +12,16 @@ Output format is a complete personnal choice, inspired by some formats I've seen ## Installation -Setup Rust using rust-up, then run in a terminal: +Setup Rust using [rustup](https://www.rust-lang.org/tools/install) and [set channels to nigthly](https://rust-lang.github.io/rustup/concepts/channels.html). + +Then run in a terminal: ```bash cargo install --git https://git.tetalab.org/Mutah/rss2json.git ``` + + ## Usage ```bash diff --git a/src/args.rs b/src/args.rs index 6dda611..4b46b7e 100644 --- a/src/args.rs +++ b/src/args.rs @@ -11,6 +11,9 @@ pub struct Args { #[clap(short, long, default_value_t = false)] pub pretty: bool, + + #[clap(long, default_value_t = 4)] + pub indentation: u16, } pub fn parse_args()-> Args { diff --git a/src/channel_lib.rs b/src/channel_lib.rs index d29c201..24e5adf 100644 --- a/src/channel_lib.rs +++ b/src/channel_lib.rs @@ -2,9 +2,9 @@ use std::fs::File; use std::io::{BufReader, Cursor}; use log::{error, info}; -use rss::Channel; +pub use rss::Channel; -pub fn build_channel(input: String) -> Channel { +pub fn build_channel(input: &String) -> Channel { let channel: Channel; if input.starts_with("http://") || input.starts_with("https://") { diff --git a/src/json_lib.rs b/src/json_lib.rs index 1dbc315..bcf57d1 100644 --- a/src/json_lib.rs +++ b/src/json_lib.rs @@ -1,9 +1,10 @@ use chrono::DateTime; -use json::{object, JsonValue}; +pub use json::{object, JsonValue}; use log::error; use rss::Channel; -pub fn build_json(channel: Channel) -> JsonValue { +// Build a JsonValue object reflecting a Channel instance +pub fn build_json(channel: &Channel) -> JsonValue { // Initialize root object with channel informations, using object macro from json crate let mut data = object! { channel: object!{ @@ -64,5 +65,6 @@ pub fn build_json(channel: Channel) -> JsonValue { // attach the items to the json data root data["items"] = items_data; + return data; } diff --git a/src/main.rs b/src/main.rs index 84f32c8..a3944a7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,54 +4,29 @@ // TODO refactor and unit tests to improve code while knowledge grows ! // TODO handle remote http feed discovery by parsing index and search for the feed link // TODO serialize to local document database CRUD -use std::fs; - -use json::JsonValue; -use rss::Channel; // use log::{debug, info, warn, error }; -use log::{error, info}; - +// use log::{error, info}; mod args; use crate::args::parse_args; mod channel_lib; -use crate::channel_lib::build_channel; +use crate::channel_lib::{build_channel, Channel}; mod json_lib; -use crate::json_lib::build_json; +use crate::json_lib::{build_json, JsonValue}; -fn main() -> std::io::Result<()> { +mod render; +use crate::render::render_json; + +fn main() { env_logger::init(); let args = parse_args(); - let channel: Channel = build_channel(args.input); + let channel: Channel = build_channel(&args.input); - let data: JsonValue = build_json(channel); + let data: JsonValue = build_json(&channel); - // output result - let output_string: String = if args.pretty { - data.pretty(4) - } else { - data.dump() - }; - - if args.output.len() > 0 { - let output_length = output_string.len(); - let filename = args.output.to_string(); - match fs::write(filename, output_string) { - Ok(_) => { - info!("saving {} characters to {}", output_length, args.output); - } - Err(e) => { - error!("{:?}", e); - } - } - Ok(()) - } else { - // no file name specified, dump json to stdout - println!("{}", output_string); - Ok(()) - } + render_json(&data, args.pretty, args.indentation, &args.output); } diff --git a/src/render.rs b/src/render.rs new file mode 100644 index 0000000..6c10b5b --- /dev/null +++ b/src/render.rs @@ -0,0 +1,28 @@ +use json::JsonValue; +use log::{error, info}; +use std::fs; + +pub fn render_json(value: &JsonValue, pretty: bool, spaces: u16, output: &String) { + // output result + let output_string: String = if pretty { + value.pretty(spaces) + } else { + value.dump() + }; + + if output.len() > 0 { + let output_length = output_string.len(); + let filename = output.to_string(); + match fs::write(filename, output_string) { + Ok(_) => { + info!("saved {} characters to {}", output_length, output); + } + Err(e) => { + error!("{:?}", e); + } + } + } else { + // no file name specified, dump json to stdout + println!("{}", output_string); + } +}