struct ExchangeCurrencyRequestsMock {
base: String,
to: String,
amount: f32,
}
use core::any::Any;
use task::api::Requests;
use std::error;
use serde_json::Value;
use serde_json::Map;
type Result<T> = std::result::Result<T, Box<dyn error::Error>>;
impl Requests for ExchangeCurrencyRequestsMock {
async fn call(&mut self) -> Result<Box<dyn Any>> {
let data = r#"
[
"USD": {
"USD": "1.0",
"PLN": "3.96",
"AUD": "1.52",
"EUR": "0.92"
},
"PLN": {
"PLN": "1.0"
"USD": "0.25",
"AUD": "0.38",
"EUR": "0.23"
}
]
"#;
let resp: Result<Box<serde_json::Value>> = Ok(serde_json::from_str(&data)?);
match resp {
Ok(value) => {
let obj: Map<String, Value> = value.as_object().unwrap().clone();
let ratio: f32 = obj[&self.base.to_ascii_uppercase()][self.to.to_ascii_uppercase()].to_string().parse()?;
return Ok(Box::new(ratio*self.amount))
},
Err(_) => {
let b: Box<dyn error::Error> = "Request got bad".into();
return Err(b)
},
};
}
}
#[tokio::test]
async fn call() {
let mut client = ExchangeCurrencyRequestsMock{
base: "USD".to_string(),
to: "AUD".to_string(),
amount: 100.0,
};
let result: std::result::Result<Box<dyn Any>, Box<dyn std::error::Error>> = client.call().await;
assert_eq!(result, 152.0);
}
How to return f32 from client.call ? I should unwrap result to get Box, then * to Box, get Any and downcast it to float32 and assert it. That's how I did, then I deleted it, because It didn't work.
I unwrapped result to get Box, then * to Box, get Any and downcast it to float32 and assert it, yet It didn't work
Looking at the docs for
Any,downcastis implemented onBox<dyn Any>, and it returns aResult<Box<T>, Box<dyn Any>>.So, all we have to do is:
This unwraps the original
Results, downcasts tof32, then unwraps again (because thedyn Anymay not be of typef32), and then moves out of the returnedBox<f32>.However, this sounds like an XY problem due to weird code architecture, perhaps the
Requeststrait should be changed to make it easier to use?