commit 82246d5972ddc33a9ec57486d1ea623763a5a301
parent 365a8e6eff692085c5e0d813954f43884624fb16
Author: cy6erlion <dev@merely.tech>
Date: Tue, 12 Jan 2021 11:51:29 +0200
Merge branch 'storage-struct'
Diffstat:
M | src/fetch.rs | | | 10 | ++++------ |
D | src/lib.rs | | | 78 | ------------------------------------------------------------------------------ |
M | src/main.rs | | | 68 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- |
M | src/storage.rs | | | 241 | +++++++++++++++++++++++++++++++++++++++---------------------------------------- |
4 files changed, 181 insertions(+), 216 deletions(-)
diff --git a/src/fetch.rs b/src/fetch.rs
@@ -1,21 +1,19 @@
// Download RFC index file
-pub fn index() -> Result<(), minreq::Error> {
+pub fn index() -> Result<Vec<String>, minreq::Error> {
println!("Fetching RFC index");
let response = minreq::get("https://www.rfc-editor.org/rfc-index.txt").send()?;
let data = scrape(response.as_str()?);
- super::storage::persist_index(data);
- Ok(())
+ Ok(data)
}
// Download RFC localy
-pub fn rfc(sn: u32) -> Result<(), minreq::Error> {
+pub fn rfc(sn: u32) -> Result<String, minreq::Error> {
println!("Fetching RFC #{}", sn);
let address = format!("https://www.rfc-editor.org/rfc/rfc{}.txt", sn);
println!("{}", address);
let response = minreq::get(&address).send()?;
- super::storage::persist_rfc(sn, response.as_str()?);
- Ok(())
+ Ok(String::from(response.as_str()?))
}
// TODO: fix bug causing not to return the last RFC
diff --git a/src/lib.rs b/src/lib.rs
@@ -1,78 +0,0 @@
-extern crate dirs_next;
-extern crate pager;
-
-use pager::Pager;
-use std::fs::File;
-use std::io::{BufReader, Read};
-use std::path::Path;
-
-mod fetch;
-pub mod storage;
-
-pub fn list_view() {
- if !storage::index_exists().unwrap() {
- // Download all RFCs
- fetch::index().unwrap();
- }
-
- let home_path = if let Some(p) = storage::get_home_path() {
- p
- } else {
- panic!("Error: 'Could not find home directory!'");
- };
-
- let path = format!("{}INDEX", home_path);
-
- let mut index = String::new();
- let f = File::open(&path).expect("Unable to open file");
- let mut br = BufReader::new(f);
- let mut dots = "";
-
- br.read_to_string(&mut index).expect("Unable to read INDEX");
-
- Pager::with_pager("less -r").setup();
-
- for line in index.lines() {
- let line_words: Vec<&str> = line.split(' ').collect();
- let summerize: String = line.chars().skip(line_words[0].len()).take(77).collect();
-
- if line.len() >= 77 {
- dots = "...";
- }
-
- println!("{} | {}{}", line_words[0], summerize, dots);
-
- dots = "";
- }
-}
-
-// Read RFC by serial number
-pub fn read_rfc(rfc_number: u32) {
- // check if RFC is downloaded
- if !storage::is_rfc_downloaded(rfc_number).unwrap() {
- // download RFC
- fetch::rfc(rfc_number).unwrap();
- }
-
- let home_path = if let Some(p) = storage::get_home_path() {
- p
- } else {
- panic!("Error: 'Could not find home directory!'");
- };
-
- let path = format!("{}{}", home_path, rfc_number);
-
- let mut rfc = String::new();
- let f = File::open(&path).expect("Unable to open file");
- let mut br = BufReader::new(f);
- br.read_to_string(&mut rfc).expect("Unable to read RFC");
-
- // Read RFC
- Pager::with_pager("less -r").setup();
- println!("{}", &rfc);
-}
-
-// Update RFC
-pub fn update() {
- fetch::index().unwrap();
-}
diff --git a/src/main.rs b/src/main.rs
@@ -1,4 +1,12 @@
use clap::{App, Arg, SubCommand};
+extern crate pager;
+
+mod fetch;
+pub mod storage;
+
+use pager::Pager;
+use std::fs::File;
+use std::io::{BufReader, Read};
fn main() {
let matches = App::new("ietf")
@@ -25,18 +33,38 @@ fn main() {
.subcommand(SubCommand::with_name("clean").about("Remove the rfc directory"))
.get_matches();
+ let storage = storage::Storage::new();
+
// Read RFC by serial number
if let Some(n) = matches.value_of("Number") {
- ietf::read_rfc(
- n.parse::<u32>()
- .expect("RFC Serial Number should be a numeric value!"),
- );
+ let rfc_number = n.parse::<u32>().unwrap();
+
+ // check if RFC is downloaded
+ if !storage.is_rfc_downloaded(rfc_number).unwrap() {
+ // download RFC
+ let rfc_data = fetch::rfc(rfc_number).unwrap();
+
+ // persist RFC
+ 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;
}
// Removes RFC by serial number
if let Some(n) = matches.value_of("Remove") {
- ietf::storage::remove(
+ storage.remove(
n.parse::<u32>()
.expect("RFC Serial Number should be a numeric value!"),
);
@@ -45,16 +73,38 @@ fn main() {
// Update RFC index
if let Some(_matches) = matches.subcommand_matches("update") {
- ietf::update();
+ storage.update_index();
return;
}
// Remove the ietf directory
if let Some(_matches) = matches.subcommand_matches("clean") {
- ietf::storage::clean();
+ storage.clean();
return;
}
- // Display RFC list view
- ietf::list_view();
+ // ---------- Display RFC list view ------------
+ 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 = "";
+
+ buffer_reader
+ .read_to_string(&mut index_data)
+ .expect("Unable to read INDEX");
+
+ Pager::with_pager("less -r").setup();
+
+ for line in index_data.lines() {
+ let line_words: Vec<&str> = line.split(' ').collect();
+ let summerize: String = line.chars().skip(line_words[0].len()).take(77).collect();
+
+ if line.len() >= 77 {
+ read_more_dots = "...";
+ }
+
+ println!("{} | {}{}", line_words[0], summerize, read_more_dots);
+
+ read_more_dots = "";
+ }
}
diff --git a/src/storage.rs b/src/storage.rs
@@ -3,147 +3,142 @@ use std::fs::OpenOptions;
use std::io::prelude::*;
use std::path::Path;
-// Save index localy
-pub fn persist_index(index: Vec<String>) {
- let home_path = if let Some(p) = get_home_path() {
- p
- } else {
- panic!("Error: 'Could not find home directory!'");
- };
-
- let index_file_path = format!("{}INDEX", home_path);
-
- let _file = File::create(&index_file_path).expect("Unable to create file");
- let mut file = OpenOptions::new()
- .write(true)
- .append(true)
- .open(&index_file_path)
- .unwrap();
-
- for rfc in index.iter() {
- if let Err(e) = writeln!(file, "{}", rfc) {
- eprintln!("Couldn't write to file: {}", e);
+pub struct Storage {
+ pub rfc_dir_path: String,
+ pub index_file_path: String,
+}
+
+impl Storage {
+ // Create new Storage instance
+ pub fn new() -> Self {
+ if let Some(home_path) = dirs_next::home_dir() {
+ let rfc_dir_path = if cfg!(unix) || cfg!(macos) {
+ format!("{}/rfc/", home_path.to_str().unwrap())
+ } else if cfg!(windows) {
+ format!("{}\\rfc\\", home_path.to_str().unwrap())
+ } else {
+ panic!("Unsupported OS");
+ };
+
+ // Check if storage directory (~/rfc) has been created
+ // otherwise create storage directory
+ if !Path::new(&rfc_dir_path).exists() {
+ // create RFC storage directory
+ std::fs::create_dir(&rfc_dir_path).unwrap();
+ }
+
+ let index_file_path = format!("{}INDEX", &rfc_dir_path);
+
+ // Check if RFC INDEX file is downloaded
+ if !Path::new(&index_file_path).exists() {
+ let _create_index =
+ File::create(&index_file_path).expect("Unable to creat INDEX file");
+
+ // Fetch remote INDEX file data
+ let data = super::fetch::index().unwrap();
+
+ // Persist RFC INDEX
+ Storage::persist_index(&index_file_path, data);
+ }
+
+ Storage {
+ rfc_dir_path,
+ index_file_path,
+ }
+ } else {
+ panic!("Error: 'Could not find home directory!'");
}
}
-}
-// Save RFC localy
-pub fn persist_rfc(rfc_number: u32, rfc: &str) {
- let home_path = if let Some(p) = get_home_path() {
- p
- } else {
- panic!("Error: 'Could not find home directory!'");
- };
-
- let rfc_file_path = format!("{}{}", home_path, rfc_number);
-
- let _file = File::create(&rfc_file_path).expect("Unable to create file");
- let mut file = OpenOptions::new()
- .write(true)
- .append(true)
- .open(rfc_file_path)
- .unwrap();
-
- if let Err(e) = writeln!(file, "{}", rfc) {
- eprintln!("Couldn't write to file: {}", e);
+ // Save index localy
+ pub fn persist_index(index_file_path: &str, data: Vec<String>) {
+ let mut file = OpenOptions::new()
+ .write(true)
+ .append(true)
+ .open(&index_file_path)
+ .unwrap();
+
+ for rfc in data.iter() {
+ if let Err(e) = writeln!(file, "{}", rfc) {
+ eprintln!("Couldn't write to file: {}", e);
+ }
+ }
}
-}
-// Removes RFC by Serial Number
-pub fn remove(rfc_number: u32) {
- let home_path = if let Some(p) = get_home_path() {
- p
- } else {
- panic!("Error: 'Could not find home directory!'");
- };
+ // Update index
+ pub fn update_index(&self) {
+ if Path::new(&self.index_file_path).exists() {
+ std::fs::remove_file(&self.index_file_path).unwrap();
+ }
+
+ let _create_index =
+ File::create(&self.index_file_path).expect("Unable to creat INDEX file");
- let rfc_file_path = format!("{}{}", home_path, rfc_number);
+ // Fetch remote INDEX file data
+ let data = super::fetch::index().unwrap();
- if Path::new(&rfc_file_path).exists() {
- std::fs::remove_file(&rfc_file_path).unwrap();
+ // Persist RFC INDEX
+ Storage::persist_index(&self.index_file_path, data);
}
-}
-// Removes the rfc directory
-pub fn clean() -> () {
- let rfc_directory_path = if let Some(p) = get_home_path() {
- p
- } else {
- panic!("Error: 'Could not find home directory!'");
- };
+ // Check if an RFC file has been downloaded locally
+ pub fn is_rfc_downloaded(&self, rfc_number: u32) -> Result<bool, ()> {
+ let rfc_file_path = format!("{}{}", self.rfc_dir_path, rfc_number);
- if Path::new(&rfc_directory_path).exists() {
- std::fs::remove_dir_all(&rfc_directory_path).unwrap();
+ if Path::new(&rfc_file_path).exists() {
+ Ok(true)
+ } else {
+ Ok(false)
+ }
}
-}
-// Check if an RFC file has been downloaded locally
-pub fn is_rfc_downloaded(rfc_number: u32) -> Result<bool, ()> {
- let home_path = if let Some(p) = get_home_path() {
- p
- } else {
- panic!("Error: 'Could not find home directory!'");
- };
-
- let rfc_file_path = format!("{}{}", &home_path, rfc_number);
-
- if Path::new(&rfc_file_path).exists() {
- Ok(true)
- } else {
- initialize_storage().unwrap();
- Ok(false)
+ // Save RFC localy
+ pub fn persist_rfc(&self, rfc_number: u32, rfc_data: &str) {
+ let rfc_file_path = format!("{}{}", self.rfc_dir_path, rfc_number);
+
+ let _file = File::create(&rfc_file_path).expect("Unable to create file");
+ let mut file = OpenOptions::new()
+ .write(true)
+ .append(true)
+ .open(rfc_file_path)
+ .unwrap();
+
+ if let Err(e) = writeln!(file, "{}", rfc_data) {
+ eprintln!("Couldn't write to file: {}", e);
+ }
}
-}
-// Check if storage directory (~/rfc) has been created
-// if it does not, create the directory
-fn initialize_storage() -> std::io::Result<()> {
- let home_path = if let Some(p) = get_home_path() {
- p
- } else {
- panic!("Error: 'Could not find home directory!'");
- };
-
- if Path::new(&home_path).exists() {
- Ok(())
- } else {
- std::fs::create_dir(&home_path)?;
- Ok(())
+ // Removes RFC by Serial Number
+ pub fn remove(&self, rfc_number: u32) {
+ let rfc_file_path = format!("{}{}", &self.rfc_dir_path, rfc_number);
+
+ if Path::new(&rfc_file_path).exists() {
+ std::fs::remove_file(&rfc_file_path).unwrap();
+ }
}
-}
-// Check if the rfc INDEX file has been downloaded
-pub fn index_exists() -> Result<bool, ()> {
- let home_path = if let Some(p) = get_home_path() {
- p
- } else {
- panic!("Error: 'Could not find home directory!'");
- };
-
- let index_file_path = format!("{}INDEX", home_path);
-
- if Path::new(&index_file_path).exists() {
- Ok(true)
- } else {
- initialize_storage().unwrap();
- Ok(false)
+ // Removes the rfc directory
+ pub fn clean(&self) {
+ if Path::new(&self.rfc_dir_path).exists() {
+ std::fs::remove_dir_all(&self.rfc_dir_path).unwrap();
+ }
}
-}
-// Get path of home directory
-// (`~/rfc/` on unix systems and `C:\Users\{NAME}` on windows)
-pub fn get_home_path() -> Option<String> {
- if let Some(home_path) = dirs_next::home_dir() {
- let path = if cfg!(unix) || cfg!(macos) {
- format!("{}/rfc/", home_path.to_str().unwrap())
- } else if cfg!(windows) {
- format!("{}\\rfc\\", home_path.to_str().unwrap())
+ // Get path of home directory
+ // (`~/rfc/` on unix systems and `C:\Users\{NAME}` on windows)
+ pub fn get_home_path() -> Option<String> {
+ if let Some(home_path) = dirs_next::home_dir() {
+ let path = if cfg!(unix) || cfg!(macos) {
+ format!("{}/rfc/", home_path.to_str().unwrap())
+ } else if cfg!(windows) {
+ format!("{}\\rfc\\", home_path.to_str().unwrap())
+ } else {
+ panic!("Unsupported OS");
+ };
+
+ Some(path)
} else {
- panic!("Unsupported OS");
- };
-
- Some(path)
- } else {
- None
+ None
+ }
}
}