diff options
Diffstat (limited to 'cli/src')
-rw-r--r-- | cli/src/api.rs | 2 | ||||
-rw-r--r-- | cli/src/api/client.rs | 23 | ||||
-rw-r--r-- | cli/src/api/connection.rs | 36 | ||||
-rw-r--r-- | cli/src/main.rs | 35 |
4 files changed, 87 insertions, 9 deletions
diff --git a/cli/src/api.rs b/cli/src/api.rs index 594530a..da7eb5b 100644 --- a/cli/src/api.rs +++ b/cli/src/api.rs @@ -4,5 +4,7 @@ // SPDX-License-Identifier: AGPL-3.0-or-later pub mod client; +pub mod connection; pub use client::Client; +pub use connection::Connection; diff --git a/cli/src/api/client.rs b/cli/src/api/client.rs index eee59b0..9c46db3 100644 --- a/cli/src/api/client.rs +++ b/cli/src/api/client.rs @@ -3,25 +3,34 @@ // // SPDX-License-Identifier: AGPL-3.0-or-later -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use std::error::Error; +use super::Connection; -#[derive(Debug, Deserialize)] +#[derive(Debug, Default, Deserialize, Serialize)] pub struct Client { + #[serde(default)] pub id: u32, + pub name: String, pub contact: Option<String>, pub address: Option<String>, pub email: String, pub phone: Option<String>, + + #[serde(default)] pub vat: bool, } impl Client { - pub fn all() -> Result<Vec<Self>, Box<dyn Error>> { - Ok(ureq::get("http://faktura.ddev.site/api/clients") - .set("Accept", "application/json") - .call()? - .into_json()?) + pub fn all(conn: Connection) -> Result<Vec<Self>, Box<dyn Error>> { + Ok(conn.get("clients")?) + } + + pub fn save(&self, conn: Connection) -> Result<(), Box<dyn Error>> { + let resp = conn.post("clients", &self)?; + + println!("{}", resp); + Ok(()) } } diff --git a/cli/src/api/connection.rs b/cli/src/api/connection.rs new file mode 100644 index 0000000..f1d7f1c --- /dev/null +++ b/cli/src/api/connection.rs @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2024 Eilertsens Kodeknekkeri +// SPDX-FileCopyrightText: 2024 Harald Eilertsen +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +use serde::{Deserialize, Serialize}; +use std::error::Error; + +pub struct Connection { + pub url: String, + pub jwt_token: String, +} + +impl Connection { + pub fn new<T: Into<String>>(url: T, jwt_token: T) -> Connection { + Connection { + url: url.into(), + jwt_token: jwt_token.into(), + } + } + + pub fn get<T: for <'de> Deserialize<'de>>(&self, resource: &str) -> Result<T, Box<dyn Error>> { + Ok(ureq::get(&format!("{}/{}", self.url, resource)) + .set("Accept", "application/json") + .call()? + .into_json()?) + } + + pub fn post<T: Serialize>(&self, resource: &str, data: &T) -> Result<String, Box<dyn Error>> { + Ok(ureq::post(&format!("{}/{}", self.url, resource)) + .set("Authorization", &format!("Bearer {}", self.jwt_token)) + .set("Content-Type", "application/json") + .send_json(&data)? + .into_string()?) + } +} diff --git a/cli/src/main.rs b/cli/src/main.rs index 4c34e18..ee10d17 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -7,11 +7,36 @@ mod api; -use api::Client; +use api::{Client, Connection}; fn main() -> Result<(), Box<dyn std::error::Error>> { - let clients = Client::all()?; + let conn = Connection::new( + std::env::var("FAKTURA_API_URL")?, + std::env::var("FAKTURA_JWT_TOKEN")? + ); + + let mut args = std::env::args().skip(1); + if let Some(cmd) = args.next() { + match cmd.as_str() { + "--list-clients" => { + list_clients(conn)?; + }, + "--add-client" => { + add_client(conn, &args.next() + .expect("expected new client json data"))?; + }, + &_ => { + println!("Unknown command: {}", cmd); + } + } + } + + Ok(()) +} + +fn list_clients(conn: Connection) -> Result<(), Box<dyn std::error::Error>> { + let clients = Client::all(conn)?; for c in clients { print!("{}: {} <{}>", c.id, c.name, c.email); @@ -32,3 +57,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { Ok(()) } + +fn add_client(conn: Connection, json: &str) -> Result<(), Box<dyn std::error::Error>> { + let client: Client = serde_json::from_str(json)?; + println!("{:?}", client); + client.save(conn) +} |