From 2b262db8d9e1a7d13f6afd812b1a21facf8c7035 Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Tue, 29 Jun 2021 13:34:16 -0300 Subject: [PATCH] Add Markdown storage --- Cargo.lock | 33 +++++++++++++++++++ Cargo.toml | 1 + src/args/mod.rs | 21 +++++++----- src/commands/mod.rs | 11 +++++++ src/config/config.rs | 18 ++++++++-- src/config/errors.rs | 9 +++++ src/config/mod.rs | 8 +++++ src/main.rs | 1 - .../markdown}/config.rs | 22 ++++++++++++- src/{filesystem => storage/markdown}/mod.rs | 0 .../markdown}/storage.rs | 0 src/storage/mod.rs | 1 + 12 files changed, 112 insertions(+), 13 deletions(-) rename src/{filesystem => storage/markdown}/config.rs (61%) rename src/{filesystem => storage/markdown}/mod.rs (100%) rename src/{filesystem => storage/markdown}/storage.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 6735087..ca82bcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "adler32" version = "1.0.4" @@ -334,6 +336,16 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + [[package]] name = "dirs-sys" version = "0.3.6" @@ -345,6 +357,17 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi 0.3.8", +] + [[package]] name = "doc-comment" version = "0.3.1" @@ -368,6 +391,7 @@ dependencies = [ "reqwest", "serde", "serde_derive", + "shellexpand", "toml", ] @@ -1691,6 +1715,15 @@ dependencies = [ "url 1.7.2", ] +[[package]] +name = "shellexpand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83bdb7831b2d85ddf4a7b148aa19d0587eddbe8671a436b7bd1182eaad0f2829" +dependencies = [ + "dirs-next", +] + [[package]] name = "siphasher" version = "0.2.3" diff --git a/Cargo.toml b/Cargo.toml index 94e3a29..5e37ec1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,3 +20,4 @@ reqwest = "0.9" serde = "*" serde_derive = "*" toml = "0.5" +shellexpand = "2.1" diff --git a/src/args/mod.rs b/src/args/mod.rs index 51a830d..5767a24 100644 --- a/src/args/mod.rs +++ b/src/args/mod.rs @@ -89,14 +89,19 @@ pub fn parse() -> Result { match matches.subcommand() { ("create", _) => Ok(Command::add_account(account_name.into())), ("remove", _) => Ok(Command::remove_account(account_name.into())), - ("storage", Some(args)) => { - let storage = - args.subcommand_name().ok_or(ParsingError::UnknownCommand)?; - Ok(Command::add_storage( - account_name.into(), - StorageType::try_from(storage)?, - )) - } + ("storage", Some(args)) => match args.subcommand() { + ("add", Some(add_args)) => { + let storage = add_args + .subcommand_name() + .ok_or(ParsingError::UnknownCommand)?; + log::debug!("Storage: {:?}", storage); + Ok(Command::add_storage( + account_name.into(), + StorageType::try_from(storage)?, + )) + } + _ => unimplemented!(), + }, _ => Err(ParsingError::UnknownCommand), } } diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 945d974..3338cc4 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -27,6 +27,8 @@ use elefren::prelude::*; use self::errors::CommandError; use crate::config::config::Config; +use crate::config::Configurable; +use crate::storage::markdown::config::MarkdownConfig; type CommandResult = Result<(), CommandError>; @@ -119,5 +121,14 @@ fn remove_account(name: &str) -> CommandResult { } fn add_storage(account: &str, storage: &StorageType) -> CommandResult { + let mut config = Config::open()?; + match storage { + StorageType::Markdown => { + let storage_config = MarkdownConfig::config()?; + config.set_storage_markdown(account, storage_config); + } + _ => unimplemented!(), + } + config.save()?; Ok(()) } diff --git a/src/config/config.rs b/src/config/config.rs index cbfb63b..e36339e 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -27,7 +27,7 @@ use serde_derive::Deserialize; use serde_derive::Serialize; use crate::config::errors::ConfigError; -use crate::filesystem::config::FilesystemConfig; +use crate::storage::markdown::config::MarkdownConfig; /// The last seen favourite #[derive(Serialize, Deserialize, Debug)] @@ -40,7 +40,7 @@ struct Favourite { struct AccountConfig { favourite: Option, mastodon: Data, - filesystem: Option, + markdown: Option, // joplin: Option, // org: Option, } @@ -78,7 +78,7 @@ impl Config { let account_data = AccountConfig { favourite: None, mastodon: configuration, - filesystem: None, + markdown: None, }; self.0.insert(name.into(), account_data); } @@ -88,6 +88,18 @@ impl Config { self.0.remove(name); } + /// Set the configuration for the markdown storage + pub fn set_storage_markdown( + &mut self, + account: &str, + config: MarkdownConfig, + ) { + match self.0.get_mut(account.into()) { + Some(account) => account.markdown = Some(config), + None => {} + } + } + /// Save the current configuration file. pub fn save(&self) -> Result<(), ConfigError> { let content = toml::to_string(&self.0)?; diff --git a/src/config/errors.rs b/src/config/errors.rs index 1d1636d..39ed776 100644 --- a/src/config/errors.rs +++ b/src/config/errors.rs @@ -25,6 +25,8 @@ pub enum ConfigError { ConfigFileIsBroken, /// There was something broken with the data and we couldn't save it properly InvalidConfiguration, + /// The select path is invalid + InvalidPath, } impl From for ConfigError { @@ -47,3 +49,10 @@ impl From for ConfigError { ConfigError::InvalidConfiguration } } + +impl From> for ConfigError { + fn from(e: shellexpand::LookupError) -> Self { + log::debug!("Shellexpand error: {:?}", e); + ConfigError::InvalidPath + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index b6ac00c..30ba57a 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -18,3 +18,11 @@ pub mod config; pub mod errors; + +use self::errors::ConfigError; + +pub trait Configurable { + fn config() -> Result + where + Self: Sized; +} diff --git a/src/main.rs b/src/main.rs index 1dc14d9..8197b9e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,6 @@ mod args; mod commands; mod config; -mod filesystem; mod storage; fn main() { diff --git a/src/filesystem/config.rs b/src/storage/markdown/config.rs similarity index 61% rename from src/filesystem/config.rs rename to src/storage/markdown/config.rs index a89518a..bf1349c 100644 --- a/src/filesystem/config.rs +++ b/src/storage/markdown/config.rs @@ -16,12 +16,32 @@ along with this program. If not, see . */ +use std::io::Write; + use serde_derive::Deserialize; use serde_derive::Serialize; +use crate::config::errors::ConfigError; +use crate::config::Configurable; + /// Configuration for the Filesystem backend #[derive(Serialize, Deserialize, Debug)] -pub struct FilesystemConfig { +pub struct MarkdownConfig { /// Path where files will be stored. pub path: String, } + +impl Configurable for MarkdownConfig { + fn config() -> Result { + print!("Base path for your files: "); + std::io::stdout().flush().expect("Failed to flush stdout!"); + + let mut path = String::new(); + std::io::stdin().read_line(&mut path)?; + let fullpath = shellexpand::full(path.trim())?; + log::debug!("Full path: {:?}", fullpath); + Ok(Self { + path: fullpath.into(), + }) + } +} diff --git a/src/filesystem/mod.rs b/src/storage/markdown/mod.rs similarity index 100% rename from src/filesystem/mod.rs rename to src/storage/markdown/mod.rs diff --git a/src/filesystem/storage.rs b/src/storage/markdown/storage.rs similarity index 100% rename from src/filesystem/storage.rs rename to src/storage/markdown/storage.rs diff --git a/src/storage/mod.rs b/src/storage/mod.rs index ea0540f..eccc3ef 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -21,4 +21,5 @@ pub mod data; pub mod helpers; // pub mod joplin; // pub mod org; +pub mod markdown; pub mod storage;