我正在使用一个第三方库,该库提供了我必须“按原样”使用的基于树的数据结构。API 返回Result<T, Error>. 我必须进行一些顺序调用并将错误转换为我的应用程序的内部错误。
use std::error::Error;
use std::fmt;
pub struct Tree {
branches: Vec<Tree>,
}
impl Tree {
pub fn new(branches: Vec<Tree>) -> Self {
Tree { branches }
}
pub fn get_branch(&self, id: usize) -> Result<&Tree, TreeError> {
self.branches.get(id).ok_or(TreeError {
description: "not found".to_string(),
})
}
}
#[derive(Debug)]
pub struct TreeError {
description: String,
}
impl Error for TreeError {
fn description(&self) -> &str {
self.description.as_str()
}
}
impl fmt::Display for TreeError {
fn fmt(&self, f: &mut fmt::Formatter) …Run Code Online (Sandbox Code Playgroud) 我有以下代码(请参阅游乐场):
use futures::{stream, Future, Stream}; // 0.1.25
use std::num::ParseIntError;
fn into_many(i: i32) -> impl Stream<Item = i32, Error = ParseIntError> {
stream::iter_ok(0..i)
}
fn convert_to_string(number: i32) -> Result<String, ParseIntError> {
Ok(number.to_string())
}
fn main() {
println!("start:");
let vec = into_many(10)
.map(|number| convert_to_string(number))
.collect()
.wait()
.unwrap();
println!("vec={:#?}", vec);
println!("finish:");
}
Run Code Online (Sandbox Code Playgroud)
它输出以下内容(即Vec<Result<i32, ParseIntError>>):
use futures::{stream, Future, Stream}; // 0.1.25
use std::num::ParseIntError;
fn into_many(i: i32) -> impl Stream<Item = i32, Error = ParseIntError> {
stream::iter_ok(0..i)
}
fn convert_to_string(number: i32) …Run Code Online (Sandbox Code Playgroud) 如果 RustOption提供了一些额外的便利方法,比如Option#flattenand Option#flat_map,那么这将是很好的, whereflatten会将 an 减少<Option<Option<T>>到Option<T>,并且flat_map会像 一样工作map,但采用返回 anOption并将其展平的方法/闭包。
flat_map 非常简单:
fn opt_flat_map< T, U, F: FnOnce(T) -> Option<U> >(opt: Option<T>, f: F) -> Option<U> {
match opt {
Some(x) => f(x),
None => None
}
}
Run Code Online (Sandbox Code Playgroud)
flatten更复杂,我真的不知道如何定义它。它可能看起来像:
fn opt_flatten<T, U>(opt: Option<T>) -> Option<U> {
match opt {
Some( Some(x) ) => flatten_option( Some(x) ),
_ => opt
}
}
Run Code Online (Sandbox Code Playgroud)
但这肯定行不通。有什么想法吗?
另外,我将如何在Option …