feat: add kxio printer to context

This commit is contained in:
Paul Campbell 2024-12-07 10:05:37 +00:00
parent 552e8d0d47
commit ae0d1b2649
11 changed files with 92 additions and 34 deletions

View file

@ -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);

View file

@ -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"),

View file

@ -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 {

View file

@ -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)*);
}}; // }};
} // }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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()
}
} }

View file

@ -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()
}
} }

View file

@ -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
} }

View file

@ -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"),

View file

@ -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?;