feat: add kxio printer to context
This commit is contained in:
parent
552e8d0d47
commit
ae0d1b2649
11 changed files with 92 additions and 34 deletions
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
use kxio::net::Response;
|
use kxio::{net::Response, print::Printer};
|
||||||
|
|
||||||
use crate::{e, s};
|
use crate::{e, s};
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ pub struct APIResult<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: for<'a> serde::Deserialize<'a>> APIResult<T> {
|
impl<T: for<'a> serde::Deserialize<'a>> APIResult<T> {
|
||||||
pub async fn new(response: kxio::net::Result<Response>) -> Self {
|
pub async fn new(response: kxio::net::Result<Response>, prt: &Printer) -> Self {
|
||||||
match response {
|
match response {
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
let text = response.text().await.unwrap_or_default();
|
let text = response.text().await.unwrap_or_default();
|
||||||
|
@ -16,7 +16,7 @@ impl<T: for<'a> serde::Deserialize<'a>> APIResult<T> {
|
||||||
let result = serde_json::from_str::<T>(&text)
|
let result = serde_json::from_str::<T>(&text)
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
e!("{e}: {text}");
|
e!(prt, "{e}: {text}");
|
||||||
e
|
e
|
||||||
})
|
})
|
||||||
.map_err(kxio::net::Error::from);
|
.map_err(kxio::net::Error::from);
|
||||||
|
|
|
@ -14,6 +14,7 @@ pub(crate) fn run(ctx: &Ctx) -> Result<()> {
|
||||||
} else {
|
} else {
|
||||||
file.write(include_str!("default-config.toml"))?;
|
file.write(include_str!("default-config.toml"))?;
|
||||||
p!(
|
p!(
|
||||||
|
ctx.prt,
|
||||||
"{}",
|
"{}",
|
||||||
template::expand(
|
template::expand(
|
||||||
include_str!("post-init-instructions.txt"),
|
include_str!("post-init-instructions.txt"),
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::path::PathBuf;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use color_eyre::eyre::eyre;
|
use color_eyre::eyre::eyre;
|
||||||
pub use config::AppConfig;
|
pub use config::AppConfig;
|
||||||
use kxio::{fs::FileSystem, net::Net};
|
use kxio::{fs::FileSystem, net::Net, print::Printer};
|
||||||
|
|
||||||
mod api_result;
|
mod api_result;
|
||||||
mod config;
|
mod config;
|
||||||
|
@ -19,6 +19,9 @@ mod tests;
|
||||||
|
|
||||||
pub const NAME: &str = "trello-to-deck";
|
pub const NAME: &str = "trello-to-deck";
|
||||||
|
|
||||||
|
pub use kxio::kxeprintln as e;
|
||||||
|
pub use kxio::kxprintln as p;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[clap(version = clap::crate_version!(), author = clap::crate_authors!(), about = clap::crate_description!())]
|
#[clap(version = clap::crate_version!(), author = clap::crate_authors!(), about = clap::crate_description!())]
|
||||||
struct Commands {
|
struct Commands {
|
||||||
|
@ -36,12 +39,14 @@ enum Command {
|
||||||
pub struct Ctx {
|
pub struct Ctx {
|
||||||
pub fs: FileSystem,
|
pub fs: FileSystem,
|
||||||
pub net: Net,
|
pub net: Net,
|
||||||
|
pub prt: Printer,
|
||||||
}
|
}
|
||||||
impl Default for Ctx {
|
impl Default for Ctx {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
fs: kxio::fs::new(PathBuf::default()),
|
fs: kxio::fs::new(PathBuf::default()),
|
||||||
net: kxio::net::new(),
|
net: kxio::net::new(),
|
||||||
|
prt: kxio::print::standard(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +55,7 @@ impl Default for Ctx {
|
||||||
pub struct FullCtx {
|
pub struct FullCtx {
|
||||||
pub fs: FileSystem,
|
pub fs: FileSystem,
|
||||||
pub net: Net,
|
pub net: Net,
|
||||||
|
pub prt: Printer,
|
||||||
pub cfg: AppConfig,
|
pub cfg: AppConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +77,7 @@ pub async fn run(ctx: Ctx) -> color_eyre::Result<()> {
|
||||||
let _ctx = FullCtx {
|
let _ctx = FullCtx {
|
||||||
fs: ctx.fs,
|
fs: ctx.fs,
|
||||||
net: ctx.net,
|
net: ctx.net,
|
||||||
|
prt: ctx.prt,
|
||||||
cfg,
|
cfg,
|
||||||
};
|
};
|
||||||
match commands.command {
|
match commands.command {
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
//
|
//
|
||||||
#[macro_export]
|
// #[macro_export]
|
||||||
macro_rules! p {
|
// macro_rules! p {
|
||||||
($($arg:tt)*) => {{
|
// ($printer:expr, $($arg:tt)*) => {{
|
||||||
println!($($arg)*);
|
// kxio::kxprintln!($printer, $($arg)*);
|
||||||
}};
|
// }};
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[macro_export]
|
// #[macro_export]
|
||||||
macro_rules! e {
|
// macro_rules! e {
|
||||||
($($arg:tt)*) => {{
|
// ($printer:expr, $($arg:tt)*) => {{
|
||||||
eprintln!($($arg)*);
|
// kxio::kxeprintln!($($arg)*);
|
||||||
}};
|
// }};
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
//
|
//
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
|
|
||||||
use trello_to_deck::{run, Ctx};
|
use trello_to_deck::{run, Ctx};
|
||||||
|
@ -8,9 +6,5 @@ use trello_to_deck::{run, Ctx};
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
#[cfg_attr(test, mutants::skip)]
|
#[cfg_attr(test, mutants::skip)]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
run(Ctx {
|
run(Ctx::default()).await
|
||||||
fs: kxio::fs::new(PathBuf::default()),
|
|
||||||
net: kxio::net::new(),
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//
|
//
|
||||||
use kxio::net::Net;
|
use kxio::net::Net;
|
||||||
|
use kxio::print::Printer;
|
||||||
|
|
||||||
use crate::api_result::APIResult;
|
use crate::api_result::APIResult;
|
||||||
use crate::{config::NextcloudConfig, f};
|
use crate::{config::NextcloudConfig, f};
|
||||||
|
@ -14,14 +15,16 @@ mod tests;
|
||||||
|
|
||||||
pub(crate) struct DeckClient<'cfg> {
|
pub(crate) struct DeckClient<'cfg> {
|
||||||
net: Net,
|
net: Net,
|
||||||
|
prt: Printer,
|
||||||
hostname: &'cfg NextcloudHostname,
|
hostname: &'cfg NextcloudHostname,
|
||||||
username: &'cfg NextcloudUsername,
|
username: &'cfg NextcloudUsername,
|
||||||
password: &'cfg NextcloudPassword,
|
password: &'cfg NextcloudPassword,
|
||||||
}
|
}
|
||||||
impl<'cfg> DeckClient<'cfg> {
|
impl<'cfg> DeckClient<'cfg> {
|
||||||
pub fn new(cfg: &'cfg NextcloudConfig, net: Net) -> Self {
|
pub fn new(cfg: &'cfg NextcloudConfig, net: Net, prt: Printer) -> Self {
|
||||||
Self {
|
Self {
|
||||||
net,
|
net,
|
||||||
|
prt,
|
||||||
hostname: &cfg.hostname,
|
hostname: &cfg.hostname,
|
||||||
username: &cfg.username,
|
username: &cfg.username,
|
||||||
password: &cfg.password,
|
password: &cfg.password,
|
||||||
|
@ -44,6 +47,7 @@ impl<'cfg> DeckClient<'cfg> {
|
||||||
.header("accept", "application/json")
|
.header("accept", "application/json")
|
||||||
.send()
|
.send()
|
||||||
.await,
|
.await,
|
||||||
|
&self.prt,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
@ -56,6 +60,40 @@ impl<'cfg> DeckClient<'cfg> {
|
||||||
.header("accept", "application/json")
|
.header("accept", "application/json")
|
||||||
.send()
|
.send()
|
||||||
.await,
|
.await,
|
||||||
|
&self.prt,
|
||||||
|
)
|
||||||
|
.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.as_str(), Some(self.password.as_str()))
|
||||||
|
.header("accept", "application/json")
|
||||||
|
.body(json.to_string())
|
||||||
|
.send()
|
||||||
|
.await,
|
||||||
|
&self.prt,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ mod client {
|
||||||
.expect("mock request");
|
.expect("mock request");
|
||||||
|
|
||||||
let cfg = given::a_nextcloud_config();
|
let cfg = given::a_nextcloud_config();
|
||||||
let deck_client = DeckClient::new(&cfg, mock_net.into());
|
let deck_client = DeckClient::new(&cfg, mock_net.into(), given::a_printer());
|
||||||
|
|
||||||
//when
|
//when
|
||||||
let result = deck_client.get_boards().await.result.expect("get boards");
|
let result = deck_client.get_boards().await.result.expect("get boards");
|
||||||
|
@ -182,7 +182,7 @@ mod client {
|
||||||
.expect("mock request");
|
.expect("mock request");
|
||||||
|
|
||||||
let cfg = given::a_nextcloud_config();
|
let cfg = given::a_nextcloud_config();
|
||||||
let deck_client = DeckClient::new(&cfg, mock_net.into());
|
let deck_client = DeckClient::new(&cfg, mock_net.into(), given::a_printer());
|
||||||
|
|
||||||
//when
|
//when
|
||||||
let result = deck_client
|
let result = deck_client
|
||||||
|
@ -221,6 +221,8 @@ mod client {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod given {
|
mod given {
|
||||||
|
use kxio::print::Printer;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub fn a_nextcloud_config() -> NextcloudConfig {
|
pub fn a_nextcloud_config() -> NextcloudConfig {
|
||||||
|
@ -235,4 +237,8 @@ mod given {
|
||||||
board_id,
|
board_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn a_printer() -> Printer {
|
||||||
|
kxio::print::test()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ mod config {
|
||||||
.join("\n"),
|
.join("\n"),
|
||||||
)
|
)
|
||||||
.expect("write file");
|
.expect("write file");
|
||||||
let ctx = given::a_context(fs.as_real(), given::a_network().into());
|
let ctx = given::a_context(fs.as_real(), given::a_network().into(), given::a_printer());
|
||||||
|
|
||||||
//when
|
//when
|
||||||
let_assert!(Ok(config) = AppConfig::load(&ctx));
|
let_assert!(Ok(config) = AppConfig::load(&ctx));
|
||||||
|
@ -72,7 +72,7 @@ mod init {
|
||||||
fn when_file_does_not_exist_should_create() {
|
fn when_file_does_not_exist_should_create() {
|
||||||
//given
|
//given
|
||||||
let fs = given::a_filesystem();
|
let fs = given::a_filesystem();
|
||||||
let ctx = given::a_context(fs.as_real(), given::a_network().into());
|
let ctx = given::a_context(fs.as_real(), given::a_network().into(), given::a_printer());
|
||||||
|
|
||||||
//when
|
//when
|
||||||
let_assert!(Ok(_) = run(&ctx));
|
let_assert!(Ok(_) = run(&ctx));
|
||||||
|
@ -92,7 +92,7 @@ mod init {
|
||||||
let file = fs.file(&path);
|
let file = fs.file(&path);
|
||||||
file.write("").expect("create file");
|
file.write("").expect("create file");
|
||||||
|
|
||||||
let ctx = given::a_context(fs.as_real(), given::a_network().into());
|
let ctx = given::a_context(fs.as_real(), given::a_network().into(), given::a_printer());
|
||||||
//when
|
//when
|
||||||
let_assert!(Err(err) = run(&ctx));
|
let_assert!(Err(err) = run(&ctx));
|
||||||
|
|
||||||
|
@ -127,12 +127,13 @@ mod given {
|
||||||
use kxio::{
|
use kxio::{
|
||||||
fs::{FileSystem, TempFileSystem},
|
fs::{FileSystem, TempFileSystem},
|
||||||
net::{MockNet, Net},
|
net::{MockNet, Net},
|
||||||
|
print::Printer,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::Ctx;
|
use crate::Ctx;
|
||||||
|
|
||||||
pub fn a_context(fs: FileSystem, net: Net) -> Ctx {
|
pub fn a_context(fs: FileSystem, net: Net, prt: Printer) -> Ctx {
|
||||||
Ctx { fs, net }
|
Ctx { fs, net, prt }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn a_filesystem() -> TempFileSystem {
|
pub fn a_filesystem() -> TempFileSystem {
|
||||||
|
@ -142,4 +143,8 @@ mod given {
|
||||||
pub fn a_network() -> MockNet {
|
pub fn a_network() -> MockNet {
|
||||||
kxio::net::mock()
|
kxio::net::mock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn a_printer() -> Printer {
|
||||||
|
kxio::print::test()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
use kxio::net::Net;
|
use kxio::{net::Net, print::Printer};
|
||||||
|
|
||||||
use crate::api_result::APIResult;
|
use crate::api_result::APIResult;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -42,6 +42,7 @@ use crate::{
|
||||||
pub async fn get_boards_that_member_belongs_to(
|
pub async fn get_boards_that_member_belongs_to(
|
||||||
auth: &TrelloAuth,
|
auth: &TrelloAuth,
|
||||||
net: &Net,
|
net: &Net,
|
||||||
|
prt: &Printer,
|
||||||
) -> APIResult<Vec<TrelloBoard>> {
|
) -> APIResult<Vec<TrelloBoard>> {
|
||||||
APIResult::new(
|
APIResult::new(
|
||||||
net.get(url(f!("/members/{}/boards?lists=open", **auth.user())))
|
net.get(url(f!("/members/{}/boards?lists=open", **auth.user())))
|
||||||
|
@ -49,6 +50,7 @@ pub async fn get_boards_that_member_belongs_to(
|
||||||
.header("Accept", "application/json")
|
.header("Accept", "application/json")
|
||||||
.send()
|
.send()
|
||||||
.await,
|
.await,
|
||||||
|
prt,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
use kxio::net::MockNet;
|
use kxio::{net::MockNet, print::Printer};
|
||||||
|
|
||||||
use crate::trello::types::auth::{TrelloApiKey, TrelloApiSecret, TrelloAuth, TrelloUser};
|
use crate::trello::types::auth::{TrelloApiKey, TrelloApiSecret, TrelloAuth, TrelloUser};
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@ pub(crate) fn a_network() -> MockNet {
|
||||||
kxio::net::mock()
|
kxio::net::mock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn a_printer() -> Printer {
|
||||||
|
kxio::print::test()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn an_auth() -> TrelloAuth {
|
pub(crate) fn an_auth() -> TrelloAuth {
|
||||||
TrelloAuth::new(
|
TrelloAuth::new(
|
||||||
TrelloApiKey::new("foo"),
|
TrelloApiKey::new("foo"),
|
||||||
|
|
|
@ -26,6 +26,7 @@ mod members {
|
||||||
async fn get_member_boards() -> TestResult {
|
async fn get_member_boards() -> TestResult {
|
||||||
//given
|
//given
|
||||||
let net = given::a_network();
|
let net = given::a_network();
|
||||||
|
let prt = given::a_printer();
|
||||||
let auth = given::an_auth();
|
let auth = given::an_auth();
|
||||||
|
|
||||||
net.on()
|
net.on()
|
||||||
|
@ -43,7 +44,7 @@ mod members {
|
||||||
])))?;
|
])))?;
|
||||||
|
|
||||||
//when
|
//when
|
||||||
let result = get_boards_that_member_belongs_to(&auth, &net.into())
|
let result = get_boards_that_member_belongs_to(&auth, &net.into(), &prt)
|
||||||
.await
|
.await
|
||||||
.result?;
|
.result?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue