Implemented debug logging to debug_logs/
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
|||||||
**/target/
|
**/target/
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
.env
|
.env
|
||||||
|
/debug_logs/
|
||||||
|
|||||||
49
Cargo.lock
generated
49
Cargo.lock
generated
@@ -159,15 +159,21 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"firefly-client",
|
"firefly-client",
|
||||||
"gocardless-client",
|
"gocardless-client",
|
||||||
|
"http",
|
||||||
|
"hyper",
|
||||||
"mockall",
|
"mockall",
|
||||||
|
"reqwest",
|
||||||
|
"reqwest-middleware",
|
||||||
"rust_decimal",
|
"rust_decimal",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"task-local-extensions",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
@@ -475,6 +481,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"reqwest-middleware",
|
||||||
"rust_decimal",
|
"rust_decimal",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -660,6 +667,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"reqwest-middleware",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -1051,6 +1059,16 @@ version = "0.3.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime_guess"
|
||||||
|
version = "2.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
|
||||||
|
dependencies = [
|
||||||
|
"mime",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -1421,6 +1439,7 @@ dependencies = [
|
|||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"mime",
|
"mime",
|
||||||
|
"mime_guess",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
@@ -1442,6 +1461,21 @@ dependencies = [
|
|||||||
"winreg",
|
"winreg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "reqwest-middleware"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a735987236a8e238bf0296c7e351b999c188ccc11477f311b82b55c93984216"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"async-trait",
|
||||||
|
"http",
|
||||||
|
"reqwest",
|
||||||
|
"serde",
|
||||||
|
"task-local-extensions",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "retain_mut"
|
name = "retain_mut"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
@@ -1778,6 +1812,15 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "task-local-extensions"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba323866e5d033818e3240feeb9f7db2c4296674e4d9e16b97b7bf8f490434e8"
|
||||||
|
dependencies = [
|
||||||
|
"pin-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termtree"
|
name = "termtree"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@@ -2016,6 +2059,12 @@ version = "0.2.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
|
|||||||
@@ -24,8 +24,11 @@ rust_decimal = { version = "1.33", features = ["serde-float"] }
|
|||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
dotenvy = "0.15"
|
dotenvy = "0.15"
|
||||||
clap = { version = "4.4", features = ["derive", "env"] }
|
clap = { version = "4.4", features = ["derive", "env"] }
|
||||||
reqwest = { version = "0.11", features = ["json", "multipart"] }
|
reqwest = { version = "0.11", default-features = false, features = ["json", "multipart", "rustls-tls"] }
|
||||||
url = "2.5"
|
url = "2.5"
|
||||||
wiremock = "0.5"
|
wiremock = "0.5"
|
||||||
tokio-test = "0.4"
|
tokio-test = "0.4"
|
||||||
mockall = "0.11"
|
mockall = "0.11"
|
||||||
|
reqwest-middleware = "0.2"
|
||||||
|
hyper = { version = "0.14", features = ["full"] }
|
||||||
|
bytes = "1.0"
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ chrono = { workspace = true }
|
|||||||
rust_decimal = { workspace = true }
|
rust_decimal = { workspace = true }
|
||||||
dotenvy = { workspace = true }
|
dotenvy = { workspace = true }
|
||||||
clap = { workspace = true }
|
clap = { workspace = true }
|
||||||
|
reqwest = { workspace = true }
|
||||||
|
|
||||||
# Core logic dependencies
|
# Core logic dependencies
|
||||||
async-trait = { workspace = true }
|
async-trait = { workspace = true }
|
||||||
@@ -23,5 +24,12 @@ async-trait = { workspace = true }
|
|||||||
firefly-client = { path = "../firefly-client" }
|
firefly-client = { path = "../firefly-client" }
|
||||||
gocardless-client = { path = "../gocardless-client" }
|
gocardless-client = { path = "../gocardless-client" }
|
||||||
|
|
||||||
|
# Debug logging dependencies
|
||||||
|
reqwest-middleware = { workspace = true }
|
||||||
|
hyper = { workspace = true }
|
||||||
|
bytes = { workspace = true }
|
||||||
|
http = "0.2"
|
||||||
|
task-local-extensions = "0.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
mockall = { workspace = true }
|
mockall = { workspace = true }
|
||||||
|
|||||||
116
banks2ff/src/debug.rs
Normal file
116
banks2ff/src/debug.rs
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
use reqwest_middleware::{Middleware, Next};
|
||||||
|
use task_local_extensions::Extensions;
|
||||||
|
use reqwest::{Request, Response};
|
||||||
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
use chrono::Utc;
|
||||||
|
use hyper::Body;
|
||||||
|
|
||||||
|
static REQUEST_COUNTER: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
|
pub struct DebugLogger {
|
||||||
|
service_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebugLogger {
|
||||||
|
pub fn new(service_name: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
service_name: service_name.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl Middleware for DebugLogger {
|
||||||
|
async fn handle(
|
||||||
|
&self,
|
||||||
|
req: Request,
|
||||||
|
extensions: &mut Extensions,
|
||||||
|
next: Next<'_>,
|
||||||
|
) -> reqwest_middleware::Result<Response> {
|
||||||
|
let request_id = REQUEST_COUNTER.fetch_add(1, Ordering::SeqCst);
|
||||||
|
let timestamp = Utc::now().format("%Y%m%d_%H%M%S");
|
||||||
|
let filename = format!("{}_{}_{}.txt", timestamp, request_id, self.service_name);
|
||||||
|
|
||||||
|
let dir = format!("./debug_logs/{}", self.service_name);
|
||||||
|
fs::create_dir_all(&dir).unwrap_or_else(|e| {
|
||||||
|
eprintln!("Failed to create debug log directory: {}", e);
|
||||||
|
});
|
||||||
|
|
||||||
|
let filepath = Path::new(&dir).join(filename);
|
||||||
|
|
||||||
|
let mut log_content = String::new();
|
||||||
|
|
||||||
|
// Curl command
|
||||||
|
log_content.push_str("# Curl command:\n");
|
||||||
|
let curl = build_curl_command(&req);
|
||||||
|
log_content.push_str(&format!("{}\n\n", curl));
|
||||||
|
|
||||||
|
// Request
|
||||||
|
log_content.push_str("# Request:\n");
|
||||||
|
log_content.push_str(&format!("{} {} HTTP/1.1\n", req.method(), req.url()));
|
||||||
|
for (key, value) in req.headers() {
|
||||||
|
log_content.push_str(&format!("{}: {}\n", key, value.to_str().unwrap_or("[INVALID]")));
|
||||||
|
}
|
||||||
|
if let Some(body) = req.body() {
|
||||||
|
if let Some(bytes) = body.as_bytes() {
|
||||||
|
log_content.push_str(&format!("\n{}", String::from_utf8_lossy(bytes)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log_content.push_str("\n\n");
|
||||||
|
|
||||||
|
// Send request and get response
|
||||||
|
let response = next.run(req, extensions).await?;
|
||||||
|
|
||||||
|
// Extract parts before consuming body
|
||||||
|
let status = response.status();
|
||||||
|
let version = response.version();
|
||||||
|
let headers = response.headers().clone();
|
||||||
|
|
||||||
|
// Response
|
||||||
|
log_content.push_str("# Response:\n");
|
||||||
|
log_content.push_str(&format!("HTTP/1.1 {} {}\n", status.as_u16(), status.canonical_reason().unwrap_or("Unknown")));
|
||||||
|
for (key, value) in &headers {
|
||||||
|
log_content.push_str(&format!("{}: {}\n", key, value.to_str().unwrap_or("[INVALID]")));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read body
|
||||||
|
let body_bytes = response.bytes().await.map_err(|e| reqwest_middleware::Error::Middleware(anyhow::anyhow!("Failed to read response body: {}", e)))?;
|
||||||
|
let body_str = String::from_utf8_lossy(&body_bytes);
|
||||||
|
log_content.push_str(&format!("\n{}", body_str));
|
||||||
|
|
||||||
|
// Write to file
|
||||||
|
if let Err(e) = fs::write(&filepath, log_content) {
|
||||||
|
eprintln!("Failed to write debug log: {}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconstruct response
|
||||||
|
let mut builder = http::Response::builder()
|
||||||
|
.status(status)
|
||||||
|
.version(version);
|
||||||
|
for (key, value) in &headers {
|
||||||
|
builder = builder.header(key, value);
|
||||||
|
}
|
||||||
|
let new_response = builder.body(Body::from(body_bytes)).unwrap();
|
||||||
|
Ok(Response::from(new_response))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_curl_command(req: &Request) -> String {
|
||||||
|
let mut curl = format!("curl -v -X {} '{}'", req.method(), req.url());
|
||||||
|
|
||||||
|
for (key, value) in req.headers() {
|
||||||
|
let value_str = value.to_str().unwrap_or("[INVALID]").replace("'", "\\'");
|
||||||
|
curl.push_str(&format!(" -H '{}: {}'", key, value_str));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(body) = req.body() {
|
||||||
|
if let Some(bytes) = body.as_bytes() {
|
||||||
|
let body_str = String::from_utf8_lossy(bytes).replace("'", "\\'");
|
||||||
|
curl.push_str(&format!(" -d '{}'", body_str));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
curl
|
||||||
|
}
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
mod adapters;
|
mod adapters;
|
||||||
mod core;
|
mod core;
|
||||||
|
mod debug;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use tracing::{info, error};
|
use tracing::{info, error};
|
||||||
use crate::adapters::gocardless::client::GoCardlessAdapter;
|
use crate::adapters::gocardless::client::GoCardlessAdapter;
|
||||||
use crate::adapters::firefly::client::FireflyAdapter;
|
use crate::adapters::firefly::client::FireflyAdapter;
|
||||||
use crate::core::sync::run_sync;
|
use crate::core::sync::run_sync;
|
||||||
|
use crate::debug::DebugLogger;
|
||||||
use gocardless_client::client::GoCardlessClient;
|
use gocardless_client::client::GoCardlessClient;
|
||||||
use firefly_client::client::FireflyClient;
|
use firefly_client::client::FireflyClient;
|
||||||
|
use reqwest_middleware::ClientBuilder;
|
||||||
use std::env;
|
use std::env;
|
||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
|
|
||||||
@@ -29,6 +32,10 @@ struct Args {
|
|||||||
/// Dry run mode: Do not create or update transactions in Firefly III.
|
/// Dry run mode: Do not create or update transactions in Firefly III.
|
||||||
#[arg(long, default_value_t = false)]
|
#[arg(long, default_value_t = false)]
|
||||||
dry_run: bool,
|
dry_run: bool,
|
||||||
|
|
||||||
|
/// Enable debug logging of HTTP requests/responses to ./debug_logs/
|
||||||
|
#[arg(long, default_value_t = false)]
|
||||||
|
debug: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
@@ -52,13 +59,28 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
let gc_url = env::var("GOCARDLESS_URL").unwrap_or_else(|_| "https://bankaccountdata.gocardless.com".to_string());
|
let gc_url = env::var("GOCARDLESS_URL").unwrap_or_else(|_| "https://bankaccountdata.gocardless.com".to_string());
|
||||||
let gc_id = env::var("GOCARDLESS_ID").expect("GOCARDLESS_ID not set");
|
let gc_id = env::var("GOCARDLESS_ID").expect("GOCARDLESS_ID not set");
|
||||||
let gc_key = env::var("GOCARDLESS_KEY").expect("GOCARDLESS_KEY not set");
|
let gc_key = env::var("GOCARDLESS_KEY").expect("GOCARDLESS_KEY not set");
|
||||||
|
|
||||||
let ff_url = env::var("FIREFLY_III_URL").expect("FIREFLY_III_URL not set");
|
let ff_url = env::var("FIREFLY_III_URL").expect("FIREFLY_III_URL not set");
|
||||||
let ff_key = env::var("FIREFLY_III_API_KEY").expect("FIREFLY_III_API_KEY not set");
|
let ff_key = env::var("FIREFLY_III_API_KEY").expect("FIREFLY_III_API_KEY not set");
|
||||||
|
|
||||||
// Clients
|
// Clients
|
||||||
let gc_client = GoCardlessClient::new(&gc_url, &gc_id, &gc_key)?;
|
let gc_client = if args.debug {
|
||||||
let ff_client = FireflyClient::new(&ff_url, &ff_key)?;
|
let client = ClientBuilder::new(reqwest::Client::new())
|
||||||
|
.with(DebugLogger::new("gocardless"))
|
||||||
|
.build();
|
||||||
|
GoCardlessClient::with_client(&gc_url, &gc_id, &gc_key, Some(client))?
|
||||||
|
} else {
|
||||||
|
GoCardlessClient::new(&gc_url, &gc_id, &gc_key)?
|
||||||
|
};
|
||||||
|
|
||||||
|
let ff_client = if args.debug {
|
||||||
|
let client = ClientBuilder::new(reqwest::Client::new())
|
||||||
|
.with(DebugLogger::new("firefly"))
|
||||||
|
.build();
|
||||||
|
FireflyClient::with_client(&ff_url, &ff_key, Some(client))?
|
||||||
|
} else {
|
||||||
|
FireflyClient::new(&ff_url, &ff_key)?
|
||||||
|
};
|
||||||
|
|
||||||
// Adapters
|
// Adapters
|
||||||
let source = GoCardlessAdapter::new(gc_client);
|
let source = GoCardlessAdapter::new(gc_client);
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ edition.workspace = true
|
|||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls"] }
|
reqwest = { workspace = true, default-features = false, features = ["json", "rustls-tls"] }
|
||||||
|
reqwest-middleware = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use reqwest::{Client, Url};
|
use reqwest::Url;
|
||||||
|
use reqwest_middleware::ClientWithMiddleware;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
@@ -8,6 +9,8 @@ use crate::models::{AccountArray, TransactionStore, TransactionArray, Transactio
|
|||||||
pub enum FireflyError {
|
pub enum FireflyError {
|
||||||
#[error("Request failed: {0}")]
|
#[error("Request failed: {0}")]
|
||||||
RequestFailed(#[from] reqwest::Error),
|
RequestFailed(#[from] reqwest::Error),
|
||||||
|
#[error("Middleware error: {0}")]
|
||||||
|
MiddlewareError(#[from] reqwest_middleware::Error),
|
||||||
#[error("API Error: {0}")]
|
#[error("API Error: {0}")]
|
||||||
ApiError(String),
|
ApiError(String),
|
||||||
#[error("URL Parse Error: {0}")]
|
#[error("URL Parse Error: {0}")]
|
||||||
@@ -16,15 +19,19 @@ pub enum FireflyError {
|
|||||||
|
|
||||||
pub struct FireflyClient {
|
pub struct FireflyClient {
|
||||||
base_url: Url,
|
base_url: Url,
|
||||||
client: Client,
|
client: ClientWithMiddleware,
|
||||||
access_token: String,
|
access_token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FireflyClient {
|
impl FireflyClient {
|
||||||
pub fn new(base_url: &str, access_token: &str) -> Result<Self, FireflyError> {
|
pub fn new(base_url: &str, access_token: &str) -> Result<Self, FireflyError> {
|
||||||
|
Self::with_client(base_url, access_token, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_client(base_url: &str, access_token: &str, client: Option<ClientWithMiddleware>) -> Result<Self, FireflyError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
base_url: Url::parse(base_url)?,
|
base_url: Url::parse(base_url)?,
|
||||||
client: Client::new(),
|
client: client.unwrap_or_else(|| reqwest_middleware::ClientBuilder::new(reqwest::Client::new()).build()),
|
||||||
access_token: access_token.to_string(),
|
access_token: access_token.to_string(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ edition.workspace = true
|
|||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls"] }
|
reqwest = { workspace = true, default-features = false, features = ["json", "rustls-tls"] }
|
||||||
|
reqwest-middleware = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use reqwest::{Client, Url};
|
use reqwest::Url;
|
||||||
|
use reqwest_middleware::ClientWithMiddleware;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
@@ -8,6 +9,8 @@ use crate::models::{TokenResponse, PaginatedResponse, Requisition, Account, Tran
|
|||||||
pub enum GoCardlessError {
|
pub enum GoCardlessError {
|
||||||
#[error("Request failed: {0}")]
|
#[error("Request failed: {0}")]
|
||||||
RequestFailed(#[from] reqwest::Error),
|
RequestFailed(#[from] reqwest::Error),
|
||||||
|
#[error("Middleware error: {0}")]
|
||||||
|
MiddlewareError(#[from] reqwest_middleware::Error),
|
||||||
#[error("API Error: {0}")]
|
#[error("API Error: {0}")]
|
||||||
ApiError(String),
|
ApiError(String),
|
||||||
#[error("Serialization error: {0}")]
|
#[error("Serialization error: {0}")]
|
||||||
@@ -18,7 +21,7 @@ pub enum GoCardlessError {
|
|||||||
|
|
||||||
pub struct GoCardlessClient {
|
pub struct GoCardlessClient {
|
||||||
base_url: Url,
|
base_url: Url,
|
||||||
client: Client,
|
client: ClientWithMiddleware,
|
||||||
secret_id: String,
|
secret_id: String,
|
||||||
secret_key: String,
|
secret_key: String,
|
||||||
access_token: Option<String>,
|
access_token: Option<String>,
|
||||||
@@ -33,9 +36,13 @@ struct TokenRequest<'a> {
|
|||||||
|
|
||||||
impl GoCardlessClient {
|
impl GoCardlessClient {
|
||||||
pub fn new(base_url: &str, secret_id: &str, secret_key: &str) -> Result<Self, GoCardlessError> {
|
pub fn new(base_url: &str, secret_id: &str, secret_key: &str) -> Result<Self, GoCardlessError> {
|
||||||
|
Self::with_client(base_url, secret_id, secret_key, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_client(base_url: &str, secret_id: &str, secret_key: &str, client: Option<ClientWithMiddleware>) -> Result<Self, GoCardlessError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
base_url: Url::parse(base_url)?,
|
base_url: Url::parse(base_url)?,
|
||||||
client: Client::new(),
|
client: client.unwrap_or_else(|| reqwest_middleware::ClientBuilder::new(reqwest::Client::new()).build()),
|
||||||
secret_id: secret_id.to_string(),
|
secret_id: secret_id.to_string(),
|
||||||
secret_key: secret_key.to_string(),
|
secret_key: secret_key.to_string(),
|
||||||
access_token: None,
|
access_token: None,
|
||||||
|
|||||||
Reference in New Issue
Block a user