refactor: Add FullCtx which is Ctx with AppConfig
This commit is contained in:
parent
ff4ad7ca60
commit
308c030f87
9 changed files with 125 additions and 124 deletions
|
@ -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,
|
||||
|
|
34
src/lib.rs
34
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)?;
|
||||
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 => init::run(&ctx)?,
|
||||
Command::Init => Err(eyre!("Config file already exists. Not overwriting it.")),
|
||||
Command::Check => todo!("check"),
|
||||
Command::Import => todo!("import"),
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,16 @@ impl DeckClient {
|
|||
.await
|
||||
}
|
||||
|
||||
pub async fn create_board(&self, title: &str, color: &str) -> APIResult<Board> {
|
||||
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<Vec<Stack>> {
|
||||
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<Card> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
10
src/tests/test-config.toml
Normal file
10
src/tests/test-config.toml
Normal file
|
@ -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
|
|
@ -1,14 +1,14 @@
|
|||
//
|
||||
pub mod api;
|
||||
// pub mod api;
|
||||
pub mod types;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
// #[cfg(test)]
|
||||
// mod tests;
|
||||
|
||||
use crate::f;
|
||||
|
||||
pub fn url(path: impl Into<String>) -> 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>) -> String {
|
||||
// let path = path.into();
|
||||
// assert!(path.starts_with("/"));
|
||||
// f!("https://api.trello.com/1{path}")
|
||||
// }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
use std::collections::HashMap;
|
||||
|
||||
//
|
||||
use derive_more::derive::Display;
|
||||
|
||||
use crate::newtype;
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue