extern crate pager;
use clap::{App, Arg, SubCommand};
use cursive::align::HAlign;
use cursive::event::EventResult;
use cursive::traits::With;
use cursive::traits::*;
use cursive::views::{Dialog, OnEventView, SelectView};
use cursive::Cursive;
use pager::Pager;
mod fetch;
mod storage;
use std::fs::File;
use std::io::{BufReader, Read};
fn main() -> Result<(), std::io::Error> {
let matches = App::new("ietf")
.version("0.2.2")
.about("CLI for reading IETF RFCs.")
.before_help("██▄██ ▄▄█▄ ▄█ ▄▄\n██ ▄█ ▄▄██ ██ ▄█\n█▄▄▄█▄▄▄██▄██▄██\n▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀")
.arg(
Arg::with_name("Number")
.short("n")
.long("number")
.value_name("serial")
.help("RFC Serial Number")
.takes_value(true),
)
.arg(
Arg::with_name("Remove")
.short("r")
.long("remove")
.value_name("serial")
.help("RFC Serial Number")
.takes_value(true),
)
.subcommand(SubCommand::with_name("update").about("Update RFC Index"))
.subcommand(SubCommand::with_name("clean").about("Remove the rfc directory"))
.get_matches();
let storage = storage::Storage::new();
if let Some(n) = matches.value_of("Number") {
let rfc_number = n.parse::<u32>().unwrap();
if !storage.is_rfc_downloaded(rfc_number).unwrap() {
println!("Fetching RFC...");
let rfc_data = fetch::rfc(rfc_number).unwrap();
storage.persist_rfc(rfc_number, &rfc_data);
}
let rfc_file_path = format!("{}{}", storage.rfc_dir_path, rfc_number);
let mut rfc_data = String::new();
let index_file = File::open(&rfc_file_path).expect("Unable to open file");
let mut buffer_reader = BufReader::new(index_file);
buffer_reader
.read_to_string(&mut rfc_data)
.expect("Unable to read RFC");
Pager::with_pager("less -r").setup();
println!("{}", rfc_data);
return Ok(());
}
if let Some(n) = matches.value_of("Remove") {
storage.remove(
n.parse::<u32>()
.expect("RFC Serial Number should be a numeric value!"),
);
return Ok(());
}
if let Some(_matches) = matches.subcommand_matches("update") {
storage.update_index();
return Ok(());
}
if let Some(_matches) = matches.subcommand_matches("clean") {
storage.clean();
return Ok(());
}
let mut siv = cursive::default();
siv.set_theme(cursive::theme::Theme::default().with(|theme| {
use cursive::theme::{BaseColor::*, Color::*, PaletteColor::*};
theme.palette[Background] = TerminalDefault;
theme.palette[Primary] = Dark(Black);
theme.palette[Secondary] = Rgb(255, 12, 42);
}));
let mut index_data = String::new();
let index_file = File::open(&storage.index_file_path).expect("Unable to open file");
let mut buffer_reader = BufReader::new(index_file);
let mut _read_more_dots = "";
let show_next_window = move |siv: &mut Cursive, rfc_title: &str| {
let rfc_title: Vec<&str> = rfc_title.split(' ').collect();
let rfc_number = rfc_title[0]
.parse::<u32>()
.expect("Could not parse RFC number");
if !storage.is_rfc_downloaded(rfc_number).unwrap() {
println!("Fetching RFC...");
let rfc_data = fetch::rfc(rfc_number).unwrap();
storage.persist_rfc(rfc_number, &rfc_data);
}
let rfc_file_path = format!("{}{}", storage.rfc_dir_path, rfc_number);
let mut rfc_data = String::new();
let index_file = File::open(&rfc_file_path).expect("Unable to open file");
let mut buffer_reader = BufReader::new(index_file);
buffer_reader
.read_to_string(&mut rfc_data)
.expect("Unable to read RFC");
siv.dump();
Pager::with_pager("less -r").setup();
println!("{}", rfc_data);
siv.quit();
};
buffer_reader
.read_to_string(&mut index_data)
.expect("Unable to read INDEX");
let lines = index_data.lines();
let mut select = SelectView::new()
.h_align(HAlign::Center)
.autojump();
select.add_all_str(lines);
select.set_on_submit(show_next_window);
let select = OnEventView::new(select)
.on_pre_event_inner('p', |s, _| {
let cb = s.select_up(1);
Some(EventResult::Consumed(Some(cb)))
})
.on_pre_event_inner('n', |s, _| {
let cb = s.select_down(1);
Some(EventResult::Consumed(Some(cb)))
});
siv.add_layer(Dialog::around(select.scrollable().fixed_size((30, 20))).title("IETF RFC INDEX"));
siv.run();
Ok(())
}