refactor: ♻️ Handle channel rendering in a separate module

This commit is contained in:
fgirault 2024-07-16 08:47:55 +02:00
parent ac67753f01
commit 75906abc47
7 changed files with 56 additions and 43 deletions

View File

@ -9,13 +9,14 @@ authors = ["François Girault <fgirault@gmail.com>"]
[dependencies] [dependencies]
rss = "2.0" rss = "2.0"
url = "2.5.2" # url = "2.5.2"
json = "0.12.4" json = "0.12.4"
clap = { version = "4.5.9", features = ["derive"] } clap = { version = "4.5.9", features = ["derive"] }
chrono = "0.4.38" chrono = "0.4.38"
env_logger = "0.11.3" env_logger = "0.11.3"
log = "0.4.22" log = "0.4.22"
reqwest = { version = "0.12.5", features = ["blocking"] } reqwest = { version = "0.12.5", features = ["blocking"] }
# regex = "1.10.5"
# polodb_core = "4.4.1" # polodb_core = "4.4.1"
# serde = "1.0.204"
# regex = "1.10.5"

View File

@ -4,7 +4,7 @@ rss2json converts rss xml feeds to a json format.
## About ## 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. 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 ## 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 ```bash
cargo install --git https://git.tetalab.org/Mutah/rss2json.git cargo install --git https://git.tetalab.org/Mutah/rss2json.git
``` ```
## Usage ## Usage
```bash ```bash

View File

@ -11,6 +11,9 @@ pub struct Args {
#[clap(short, long, default_value_t = false)] #[clap(short, long, default_value_t = false)]
pub pretty: bool, pub pretty: bool,
#[clap(long, default_value_t = 4)]
pub indentation: u16,
} }
pub fn parse_args()-> Args { pub fn parse_args()-> Args {

View File

@ -2,9 +2,9 @@ use std::fs::File;
use std::io::{BufReader, Cursor}; use std::io::{BufReader, Cursor};
use log::{error, info}; 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; let channel: Channel;
if input.starts_with("http://") || input.starts_with("https://") { if input.starts_with("http://") || input.starts_with("https://") {

View File

@ -1,9 +1,10 @@
use chrono::DateTime; use chrono::DateTime;
use json::{object, JsonValue}; pub use json::{object, JsonValue};
use log::error; use log::error;
use rss::Channel; 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 // Initialize root object with channel informations, using object macro from json crate
let mut data = object! { let mut data = object! {
channel: object!{ channel: object!{
@ -64,5 +65,6 @@ pub fn build_json(channel: Channel) -> JsonValue {
// attach the items to the json data root // attach the items to the json data root
data["items"] = items_data; data["items"] = items_data;
return data; return data;
} }

View File

@ -4,54 +4,29 @@
// TODO refactor and unit tests to improve code while knowledge grows ! // 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 handle remote http feed discovery by parsing index and search for the feed link
// TODO serialize to local document database CRUD // TODO serialize to local document database CRUD
use std::fs;
use json::JsonValue;
use rss::Channel;
// use log::{debug, info, warn, error }; // use log::{debug, info, warn, error };
use log::{error, info}; // use log::{error, info};
mod args; mod args;
use crate::args::parse_args; use crate::args::parse_args;
mod channel_lib; mod channel_lib;
use crate::channel_lib::build_channel; use crate::channel_lib::{build_channel, Channel};
mod json_lib; 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(); env_logger::init();
let args = parse_args(); 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 render_json(&data, args.pretty, args.indentation, &args.output);
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(())
}
} }

28
src/render.rs Normal file
View File

@ -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);
}
}