From 210ca401567f73f19024478cb8ae7843d349afb0 Mon Sep 17 00:00:00 2001 From: DanGould Date: Fri, 20 Oct 2023 14:53:36 -0400 Subject: [PATCH] [draft] tinyjson --- payjoin-cli/Cargo.lock | 9 +++++-- payjoin/Cargo.toml | 3 +-- payjoin/src/send/error.rs | 50 +++++++++++++++++++-------------------- payjoin/src/send/mod.rs | 8 ++----- 4 files changed, 34 insertions(+), 36 deletions(-) diff --git a/payjoin-cli/Cargo.lock b/payjoin-cli/Cargo.lock index f83fa5e1..05078967 100644 --- a/payjoin-cli/Cargo.lock +++ b/payjoin-cli/Cargo.lock @@ -1118,8 +1118,7 @@ dependencies = [ "bitcoin", "log", "rand", - "serde", - "serde_json", + "tinyjson", "url", ] @@ -1702,6 +1701,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "tinyjson" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ab95735ea2c8fd51154d01e39cf13912a78071c2d89abc49a7ef102a7dd725a" + [[package]] name = "tinyvec" version = "1.6.0" diff --git a/payjoin/Cargo.toml b/payjoin/Cargo.toml index 7f5ac3f1..efe03e55 100644 --- a/payjoin/Cargo.toml +++ b/payjoin/Cargo.toml @@ -22,8 +22,7 @@ bitcoin = { version = "0.30.0", features = ["base64"] } bip21 = "0.3.1" log = { version = "0.4.14"} rand = { version = "0.8.4", optional = true } -serde = { version = "1.0.107", features = ["derive"] } -serde_json = "1.0" +tinyjson = "2" url = "2.2.2" [dev-dependencies] diff --git a/payjoin/src/send/error.rs b/payjoin/src/send/error.rs index 0437d8fd..c738a681 100644 --- a/payjoin/src/send/error.rs +++ b/payjoin/src/send/error.rs @@ -211,8 +211,6 @@ impl From for CreateRequestError { fn from(value: InternalCreateRequestError) -> Self { CreateRequestError(value) } } -use serde::Deserialize; - pub enum ResponseError { // Well known errors with internal message for logs as String WellKnown(WellKnownError, String), @@ -222,6 +220,30 @@ pub enum ResponseError { Validation(ValidationError), } +impl ResponseError { + pub fn from_json(json: &str) -> Self { + use std::convert::TryInto; + + use tinyjson::{JsonParser, JsonValue}; + + let parsed: JsonValue = json.parse().unwrap(); + //.unwrap_or_else( |_| ResponseError::Validation(InternalValidationError::Parse.into())); + let maybe_code = parsed["errorCode"].get(); + let maybe_message = parsed["message"].get(); + if let (Some(error_code), Some(message)) = (maybe_code, maybe_message) { + let well_known_error = WellKnownError::from_str(&error_code); + + if let Some(wk_error) = well_known_error { + ResponseError::WellKnown(wk_error, message.to_string()) + } else { + ResponseError::Unrecognized(error_code.to_string(), message.to_string()) + } + } else { + ResponseError::Validation(InternalValidationError::Parse.into()) + } + } +} + impl From for ResponseError { fn from(value: InternalValidationError) -> Self { Self::Validation(ValidationError { internal: value }) @@ -255,32 +277,8 @@ impl fmt::Debug for ResponseError { } } -impl<'de> Deserialize<'de> for ResponseError { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let res = RawResponseError::deserialize(deserializer)?; - - let well_known_error = WellKnownError::from_str(&res.error_code); - - if let Some(wk_error) = well_known_error { - Ok(ResponseError::WellKnown(wk_error, res.message)) - } else { - Ok(ResponseError::Unrecognized(res.error_code, res.message)) - } - } -} - impl std::error::Error for ResponseError {} -#[derive(Debug, Deserialize)] -struct RawResponseError { - #[serde(rename = "errorCode")] - error_code: String, - message: String, -} - #[derive(Debug)] pub enum WellKnownError { Unavailable, diff --git a/payjoin/src/send/mod.rs b/payjoin/src/send/mod.rs index 68592581..07f2adf8 100644 --- a/payjoin/src/send/mod.rs +++ b/payjoin/src/send/mod.rs @@ -354,13 +354,9 @@ impl Context { ) -> Result { let mut res_str = String::new(); response.read_to_string(&mut res_str).map_err(InternalValidationError::Io)?; - let proposal = Psbt::from_str(&res_str).or_else(|_| { + let proposal = Psbt::from_str(&res_str).map_err(|_| { // That wasn't a valid PSBT. Maybe it's a valid error response? - serde_json::from_str::(&res_str) - // which isn't the Ok result, it's actually an error. - .map(|e| Err(e)) - // if not, we have an invalid response - .unwrap_or_else(|_| Err(InternalValidationError::Parse.into())) + ResponseError::from_json(&res_str) })?; self.process_proposal(proposal).map(Into::into).map_err(Into::into) }