Skip to content

Commit

Permalink
Merge pull request zingolabs#677 from fluidvanadium/cleanup_implblocks
Browse files Browse the repository at this point in the history
consolidated lightclient impl blocks
  • Loading branch information
fluidvanadium authored Nov 13, 2023
2 parents 9349ee0 + ed85901 commit beeff59
Showing 1 changed file with 98 additions and 99 deletions.
197 changes: 98 additions & 99 deletions zingolib/src/lightclient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1705,106 +1705,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<f64, PriceReprError> {
if let Some(value) = from_gemini.get("price") {
if let Some(stringable) = value.as_str() {
if let Ok(parsed) = stringable.parse::<f64>() {
Ok(parsed)
} else {
Err(PriceReprError::NotParseable)
}
} else {
Err(PriceReprError::NoAsStrValue)
}
} else {
Err(PriceReprError::NoValue)
}
}

async fn get_recent_median_price_from_gemini() -> Result<f64, PriceFetchError> {
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::<Value>().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<f64> = 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,
Expand Down Expand Up @@ -2001,6 +1902,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<f64, PriceReprError> {
if let Some(value) = from_gemini.get("price") {
if let Some(stringable) = value.as_str() {
if let Ok(parsed) = stringable.parse::<f64>() {
Ok(parsed)
} else {
Err(PriceReprError::NotParseable)
}
} else {
Err(PriceReprError::NoAsStrValue)
}
} else {
Err(PriceReprError::NoValue)
}
}

async fn get_recent_median_price_from_gemini() -> Result<f64, PriceFetchError> {
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::<Value>().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<f64> = 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")]
Expand Down

0 comments on commit beeff59

Please sign in to comment.