From 1263c60626a98d9ffe3ada6a52bb683e52b0a7d6 Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Mon, 13 Nov 2023 20:06:50 +0000 Subject: [PATCH] consolidated lightclient impl blocks --- zingolib/src/lightclient.rs | 197 ++++++++++++++++++------------------ 1 file changed, 98 insertions(+), 99 deletions(-) diff --git a/zingolib/src/lightclient.rs b/zingolib/src/lightclient.rs index 565ad93e0..ebf8cacd8 100644 --- a/zingolib/src/lightclient.rs +++ b/zingolib/src/lightclient.rs @@ -1745,106 +1745,7 @@ impl LightClient { Err(ZingoLibError::NoWalletLocation) } } -} - -use serde_json::Value; - -enum PriceFetchError { - ReqwestError(String), - NotJson, - NoElements, - PriceReprError(PriceReprError), - NanValue, -} - -impl std::fmt::Display for PriceFetchError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use PriceFetchError::*; - f.write_str(&match self { - ReqwestError(e) => format!("ReqwestError: {}", e), - NotJson => "NotJson".to_string(), - NoElements => "NoElements".to_string(), - PriceReprError(e) => format!("PriceReprError: {}", e), - NanValue => "NanValue".to_string(), - }) - } -} - -enum PriceReprError { - NoValue, - NoAsStrValue, - NotParseable, -} -impl std::fmt::Display for PriceReprError { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use PriceReprError::*; - fmt.write_str(match self { - NoValue => "NoValue", - NoAsStrValue => "NoAsStrValue", - NotParseable => "NotParseable", - }) - } -} -fn repr_price_as_f64(from_gemini: &Value) -> Result { - if let Some(value) = from_gemini.get("price") { - if let Some(stringable) = value.as_str() { - if let Ok(parsed) = stringable.parse::() { - Ok(parsed) - } else { - Err(PriceReprError::NotParseable) - } - } else { - Err(PriceReprError::NoAsStrValue) - } - } else { - Err(PriceReprError::NoValue) - } -} - -async fn get_recent_median_price_from_gemini() -> Result { - let httpget = - match reqwest::get("https://api.gemini.com/v1/trades/zecusd?limit_trades=11").await { - Ok(httpresponse) => httpresponse, - Err(e) => { - return Err(PriceFetchError::ReqwestError(e.to_string())); - } - }; - let serialized = match httpget.json::().await { - Ok(asjson) => asjson, - Err(_) => { - return Err(PriceFetchError::NotJson); - } - }; - let elements = match serialized.as_array() { - Some(elements) => elements, - None => { - return Err(PriceFetchError::NoElements); - } - }; - let mut trades: Vec = match elements.iter().map(repr_price_as_f64).collect() { - Ok(trades) => trades, - Err(e) => { - return Err(PriceFetchError::PriceReprError(e)); - } - }; - if trades.iter().any(|x| x.is_nan()) { - return Err(PriceFetchError::NanValue); - } - // NOTE: This code will panic if a value is received that: - // 1. was parsed from a string to an f64 - // 2. is not a NaN - // 3. cannot be compared to an f64 - // TODO: Show that this is impossible, or write code to handle - // that case. - trades.sort_by(|a, b| { - a.partial_cmp(b) - .expect("a and b are non-nan f64, I think that makes them comparable") - }); - Ok(trades[5]) -} - -impl LightClient { fn unspent_pending_spent( &self, note: JsonValue, @@ -2041,6 +1942,104 @@ impl LightClient { res } } + +use serde_json::Value; + +enum PriceFetchError { + ReqwestError(String), + NotJson, + NoElements, + PriceReprError(PriceReprError), + NanValue, +} + +impl std::fmt::Display for PriceFetchError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use PriceFetchError::*; + f.write_str(&match self { + ReqwestError(e) => format!("ReqwestError: {}", e), + NotJson => "NotJson".to_string(), + NoElements => "NoElements".to_string(), + PriceReprError(e) => format!("PriceReprError: {}", e), + NanValue => "NanValue".to_string(), + }) + } +} + +enum PriceReprError { + NoValue, + NoAsStrValue, + NotParseable, +} + +impl std::fmt::Display for PriceReprError { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use PriceReprError::*; + fmt.write_str(match self { + NoValue => "NoValue", + NoAsStrValue => "NoAsStrValue", + NotParseable => "NotParseable", + }) + } +} +fn repr_price_as_f64(from_gemini: &Value) -> Result { + if let Some(value) = from_gemini.get("price") { + if let Some(stringable) = value.as_str() { + if let Ok(parsed) = stringable.parse::() { + Ok(parsed) + } else { + Err(PriceReprError::NotParseable) + } + } else { + Err(PriceReprError::NoAsStrValue) + } + } else { + Err(PriceReprError::NoValue) + } +} + +async fn get_recent_median_price_from_gemini() -> Result { + let httpget = + match reqwest::get("https://api.gemini.com/v1/trades/zecusd?limit_trades=11").await { + Ok(httpresponse) => httpresponse, + Err(e) => { + return Err(PriceFetchError::ReqwestError(e.to_string())); + } + }; + let serialized = match httpget.json::().await { + Ok(asjson) => asjson, + Err(_) => { + return Err(PriceFetchError::NotJson); + } + }; + let elements = match serialized.as_array() { + Some(elements) => elements, + None => { + return Err(PriceFetchError::NoElements); + } + }; + let mut trades: Vec = match elements.iter().map(repr_price_as_f64).collect() { + Ok(trades) => trades, + Err(e) => { + return Err(PriceFetchError::PriceReprError(e)); + } + }; + if trades.iter().any(|x| x.is_nan()) { + return Err(PriceFetchError::NanValue); + } + // NOTE: This code will panic if a value is received that: + // 1. was parsed from a string to an f64 + // 2. is not a NaN + // 3. cannot be compared to an f64 + // TODO: Show that this is impossible, or write code to handle + // that case. + trades.sort_by(|a, b| { + a.partial_cmp(b) + .expect("a and b are non-nan f64, I think that makes them comparable") + }); + Ok(trades[5]) +} + #[cfg(feature = "lightclient-deprecated")] mod deprecated; #[cfg(feature = "test-features")]