I've been following a Rust tutorial where two versions of a function are purported to generate the same results:
Version 1:
pub fn get_transactions(fname:&str) -> Result<Vec<Transaction>,String> {
let s = match std::fs::read_to_string(fname){
Ok(v)=>v,
Err(e)=> return Err(e.to_string()),
};
let t:Vec<Transaction> = match serde_json::from_str(&s) {
Ok(v)=>v,
Err(e)=> return Err(e.to_string()),
};
Ok(t)
}
Version 2:
fn get_transactions_b(fname:&str) -> Result<Vec<Transaction>,String> {
std::fs::read_to_string(fname)
.map_err(|e| e.to_string())
.and_then(|ld| serde_json::from_str(&ld) )
.map_err(|e| e.to_string())
}
However, I get the following message for version 2:
mismatched types
expected struct std::string::String
, found struct serde_json::error::Error
note: expected enum std::result::Result<_, std::string::String>
found enum std::result::Result<_, serde_json::error::Error>
help: try using a variant of the expected enum: _::_serde::export::Ok(serde_json::from_str(&ld))
,
which I been unable to make head or tail out of:
Hovering over ld closure argument
|ld|
in VS Code it says it's of typestd::string::String
Hovering over the ld in the
from_str(&ld)
I get the message.Now I understand a
Result
is comprised of anOk
and anErr
, but I thought the combinator chaining would have worked.The compiler suggested fix doesn't work either.
- (or make sense): What is the
_::_
all about? - Why would the
Ok
not be inside the from_str?
- (or make sense): What is the
What would you have to do to make version 2 work?
Here's the Result with the methods for combinators in the Rust docs.
Cargo.toml
[dependencies]
serde = "1.0.115"
serde_derive = "1.0.115"
serde_json = "1.0.57"
- cargo 1.45.1
- rustc 1.45.2
Result
s need to have sameError
type to combine them. For your problem you need to remove the firstmap_err(|e| e.to_string())
, it changes the type ofError
as a result you cannotserde_json::from_str(&ld)
insideand_then
because theirError
type doesn't match. – Cioffredmap_err
like thisand_then(|ld| serde_json::from_str(&ld).map_err(|e| e.to_string());
. With this way both will have the same error type, – Cioffredstd::io::Error
, found structserde_json::error::Error
(I thought whole purpose of combinators was to be able to chain) – Gangplank