Если оба типа ошибок и типов элементов неоднородны, и вы знаете сколько фьючерсов вы объедините в цепочку, самый простой способ сделать это - создать непогрешимый Future
(потому что это то, что на самом деле остается вашим будущим будущимis) тип Item
которого является кортежем всех промежуточных результатов.
Это может быть относительно просто реализовано простым построением цепочки:
let future1_casted = future1.then(future::ok::<Result<_, _>, ()>);
let future2_casted = future2.then(future::ok::<Result<_, _>, ()>);
let chain = future1_casted
.and_then(|result1| future2_casted.map(|result2| (result1, result2)));
ссылка на игровую площадку
Последний тип будущего - это кортеж, содержащий все результаты фьючерсов.
Если вы не знаете, сколько фьючерсов вы объединяете в цепочки, вам нужно будет усилить свои требования и четко знать заранеевремя возможные типы возврата вашего будущего.Поскольку без макроса невозможно создать кортеж произвольного размера, вам нужно будет сохранить промежуточные результаты в структуре, требующей однородных типов.
Чтобы решить эту проблему, определив кортежи, содержащие ваши типы,например, для ошибок, требуется:
#[derive(PartialEq, Debug)]
pub enum MyError {
Utf16Error(char::DecodeUtf16Error),
ParseError(num::ParseIntError)
}
impl From<char::DecodeUtf16Error> for MyError {
fn from(e: char::DecodeUtf16Error) -> Self {
MyError::Utf16Error(e)
}
}
impl From<num::ParseIntError> for MyError {
fn from(e: num::ParseIntError) -> Self {
MyError::ParseError(e)
}
}
Оттуда объединение фьючерсов идет по тому же маршруту, что и раньше - превратить ошибочное будущее в безошибочное возвращение Result<_, _>
, а затем объединить в структуру, подобную Vec
с future::loop_fn()