diff --git a/src/config.rs b/src/config.rs index 224bb46..1824515 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,27 +4,22 @@ use color_eyre::Result; use crate::{ f, nextcloud::model::{NextcloudBoardId, NextcloudHostname, NextcloudPassword, NextcloudUsername}, - s, Ctx, NAME, + s, + trello::types::{ + auth::{TrelloApiKey, TrelloApiSecret}, + TrelloBoardName, + }, + Ctx, NAME, }; -#[derive(Clone, Debug, derive_more::From, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize)] +#[derive(Clone, Debug, derive_more::From, PartialEq, Eq, serde::Deserialize)] pub(crate) struct TrelloConfig { - pub(crate) api_key: String, - pub(crate) api_secret: String, - pub(crate) board_name: String, + pub(crate) api_key: TrelloApiKey, + pub(crate) api_secret: TrelloApiSecret, + pub(crate) board_name: TrelloBoardName, } -#[derive( - Clone, - Debug, - derive_more::From, - PartialEq, - Eq, - PartialOrd, - Ord, - serde::Deserialize, - derive_more::Constructor, -)] +#[derive(Clone, Debug, derive_more::From, PartialEq, Eq, serde::Deserialize)] pub(crate) struct NextcloudConfig { pub(crate) hostname: NextcloudHostname, pub(crate) username: NextcloudUsername, @@ -33,15 +28,7 @@ pub(crate) struct NextcloudConfig { } #[derive( - Clone, - Debug, - derive_more::From, - PartialEq, - Eq, - PartialOrd, - Ord, - derive_more::AsRef, - serde::Deserialize, + Clone, Debug, derive_more::From, PartialEq, Eq, derive_more::AsRef, serde::Deserialize, )] pub struct AppConfig { pub(crate) trello: TrelloConfig, diff --git a/src/lib.rs b/src/lib.rs index 093234f..cdd52ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ use std::path::PathBuf; use clap::Parser; +use color_eyre::eyre::eyre; pub use config::AppConfig; use kxio::{fs::FileSystem, net::Net}; @@ -11,7 +12,7 @@ mod init; mod macros; pub mod nextcloud; mod template; -// mod trello; +mod trello; #[cfg(test)] mod tests; @@ -45,17 +46,38 @@ impl Default for Ctx { } } +#[derive(Clone)] +pub struct FullCtx { + pub fs: FileSystem, + pub net: Net, + pub cfg: AppConfig, +} + #[cfg_attr(test, mutants::skip)] pub async fn run(ctx: Ctx) -> color_eyre::Result<()> { color_eyre::install()?; let commands = Commands::parse(); - let _cfg = config::AppConfig::load(&ctx)?; - match commands.command { - Command::Init => init::run(&ctx)?, - Command::Check => todo!("check"), - Command::Import => todo!("import"), - }; - - Ok(()) + let cfg = AppConfig::load(&ctx); + match cfg { + Err(err) => { + if matches!(commands.command, Command::Init) { + init::run(&ctx) + } else { + Err(eyre!("Missing or invalid config: {err}")) + } + } + Ok(cfg) => { + let _ctx = FullCtx { + fs: ctx.fs, + net: ctx.net, + cfg, + }; + match commands.command { + Command::Init => Err(eyre!("Config file already exists. Not overwriting it.")), + Command::Check => todo!("check"), + Command::Import => todo!("import"), + } + } + } } diff --git a/src/nextcloud/mod.rs b/src/nextcloud/mod.rs index df3af82..d4e856b 100644 --- a/src/nextcloud/mod.rs +++ b/src/nextcloud/mod.rs @@ -4,6 +4,7 @@ use kxio::net::Net; use crate::api_result::APIResult; use crate::{config::NextcloudConfig, f}; +use crate::nextcloud::model::{NextcloudHostname, NextcloudPassword, NextcloudUsername}; use model::{Board, Card, NextcloudBoardId, Stack}; pub mod model; @@ -11,20 +12,19 @@ pub mod model; #[cfg(test)] mod tests; -pub(crate) struct DeckClient { +pub(crate) struct DeckClient<'cfg> { net: Net, - hostname: String, - username: String, - password: String, + hostname: &'cfg NextcloudHostname, + username: &'cfg NextcloudUsername, + password: &'cfg NextcloudPassword, } - -impl DeckClient { - pub fn new(cfg: &NextcloudConfig, net: Net) -> Self { +impl<'cfg> DeckClient<'cfg> { + pub fn new(cfg: &'cfg NextcloudConfig, net: Net) -> Self { Self { net, - hostname: cfg.hostname.to_string(), - username: cfg.username.to_string(), - password: cfg.password.to_string(), + hostname: &cfg.hostname, + username: &cfg.username, + password: &cfg.password, } } @@ -40,7 +40,7 @@ impl DeckClient { APIResult::new( self.net .get(self.url("boards")) - .basic_auth(&self.username, Some(&self.password)) + .basic_auth(self.username.as_str(), Some(self.password.as_str())) .header("accept", "application/json") .send() .await, @@ -48,66 +48,15 @@ impl DeckClient { .await } - pub async fn create_board(&self, title: &str, color: &str) -> APIResult { - APIResult::new( - self.net - .post(self.url("boards")) - .basic_auth(&self.username, Some(&self.password)) - .header("accept", "application/json") - .body( - serde_json::json!({ - "title": title, - "color": color - }) - .to_string(), - ) - .send() - .await, - ) - .await - } - pub async fn get_stacks(&self, board_id: NextcloudBoardId) -> APIResult> { APIResult::new( self.net .get(self.url(f!("boards/{board_id}/stacks"))) - .basic_auth(&self.username, Some(&self.password)) + .basic_auth(self.username.as_str(), Some(self.password.as_str())) .header("accept", "application/json") .send() .await, ) .await } - - pub async fn create_card( - &self, - board_id: i64, - stack_id: i64, - title: &str, - description: Option<&str>, - ) -> APIResult { - let url = format!( - "https://{}/index.php/apps/deck/api/v1.0/boards/{}/stacks/{}/cards", - self.hostname, board_id, stack_id - ); - - let mut json = serde_json::json!({ - "title": title, - }); - - if let Some(desc) = description { - json["description"] = serde_json::Value::String(desc.to_string()); - } - - APIResult::new( - self.net - .post(&url) - .basic_auth(&self.username, Some(&self.password)) - .header("accept", "application/json") - .body(json.to_string()) - .send() - .await, - ) - .await - } } diff --git a/src/nextcloud/tests.rs b/src/nextcloud/tests.rs index f0a5302..61a7109 100644 --- a/src/nextcloud/tests.rs +++ b/src/nextcloud/tests.rs @@ -17,7 +17,12 @@ mod config { let username = NextcloudUsername::new("username"); let password = NextcloudPassword::new("password"); let board_id = NextcloudBoardId::new(2); - let cfg = NextcloudConfig::new(hostname.clone(), username, password, board_id); + let cfg = NextcloudConfig { + hostname: hostname.clone(), + username, + password, + board_id, + }; //when //then @@ -31,7 +36,12 @@ mod config { let username = NextcloudUsername::new("username"); let password = NextcloudPassword::new("password"); let board_id = NextcloudBoardId::new(2); - let cfg = NextcloudConfig::new(hostname, username.clone(), password, board_id); + let cfg = NextcloudConfig { + hostname, + username: username.clone(), + password, + board_id, + }; //when //then @@ -45,7 +55,12 @@ mod config { let username = NextcloudUsername::new("username"); let password = NextcloudPassword::new("password"); let board_id = NextcloudBoardId::new(2); - let cfg = NextcloudConfig::new(hostname, username, password.clone(), board_id); + let cfg = NextcloudConfig { + hostname, + username, + password: password.clone(), + board_id, + }; //when //then @@ -59,7 +74,12 @@ mod config { let username = NextcloudUsername::new("username"); let password = NextcloudPassword::new("password"); let board_id = NextcloudBoardId::new(2); - let cfg = NextcloudConfig::new(hostname, username, password, board_id); + let cfg = NextcloudConfig { + hostname, + username, + password, + board_id, + }; //when //then @@ -208,6 +228,11 @@ mod given { let username = NextcloudUsername::new("username"); let password = NextcloudPassword::new("password"); let board_id = NextcloudBoardId::new(2); - NextcloudConfig::new(hostname, username, password, board_id) + NextcloudConfig { + hostname, + username, + password, + board_id, + } } } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index be43caa..55bb3a3 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -44,9 +44,9 @@ mod config { config, AppConfig { trello: TrelloConfig { - api_key: s!("trello-api-key"), - api_secret: s!("trello-api-secret"), - board_name: s!("trello-board-name"), + api_key: s!("trello-api-key").into(), + api_secret: s!("trello-api-secret").into(), + board_name: s!("trello-board-name").into(), }, nextcloud: NextcloudConfig { hostname: s!("nextcloud-hostname").into(), diff --git a/src/tests/test-config.toml b/src/tests/test-config.toml new file mode 100644 index 0000000..fcbe03a --- /dev/null +++ b/src/tests/test-config.toml @@ -0,0 +1,10 @@ +[trello] +api_key = "trello-api-key" +api_secret = "trello-api-secret" +board_name = "trello-board-name" + +[nextcloud] +hostname = "nextcloud-hostname" +username = "nextcloud-username" +password = "nextcloud-password" +board_id = 321 \ No newline at end of file diff --git a/src/trello/mod.rs b/src/trello/mod.rs index 41660e0..c50c077 100644 --- a/src/trello/mod.rs +++ b/src/trello/mod.rs @@ -1,14 +1,14 @@ // -pub mod api; +// pub mod api; pub mod types; #[cfg(test)] mod tests; -use crate::f; - -pub fn url(path: impl Into) -> String { - let path = path.into(); - assert!(path.starts_with("/")); - f!("https://api.trello.com/1{path}") -} +// use crate::f; +// +// pub fn url(path: impl Into) -> String { +// let path = path.into(); +// assert!(path.starts_with("/")); +// f!("https://api.trello.com/1{path}") +// } diff --git a/src/trello/types/auth.rs b/src/trello/types/auth.rs index d398fbb..79b4ba2 100644 --- a/src/trello/types/auth.rs +++ b/src/trello/types/auth.rs @@ -1,6 +1,6 @@ +// use std::collections::HashMap; -// use derive_more::derive::Display; use crate::newtype; diff --git a/src/trello/types/mod.rs b/src/trello/types/mod.rs index a168aa4..b3f8bf2 100644 --- a/src/trello/types/mod.rs +++ b/src/trello/types/mod.rs @@ -1,23 +1,30 @@ pub(crate) mod auth; -pub(crate) mod board; +// pub(crate) mod board; // mod card; -mod list; +// mod list; // mod new_card; use derive_more::derive::Display; use crate::newtype; -newtype!(TrelloBoardId, String, Display, "Board ID"); -newtype!(TrelloBoardName, String, Display, "Board Name"); -newtype!(TrelloListId, String, "List ID"); +// newtype!(TrelloBoardId, String, Display, "Board ID"); newtype!( - TrelloListName, + TrelloBoardName, String, Display, PartialOrd, Ord, - "List Name" + "Board Name" ); -newtype!(TrelloCardId, String, Display, "Card ID"); -newtype!(TrelloCardName, String, Display, "Card Name"); +// newtype!(TrelloListId, String, "List ID"); +// newtype!( +// TrelloListName, +// String, +// Display, +// PartialOrd, +// Ord, +// "List Name" +// ); +// newtype!(TrelloCardId, String, Display, "Card ID"); +// newtype!(TrelloCardName, String, Display, "Card Name");