I very much might. (And I very much might not. If anyone else wants to beat me to the punch, please do, and stick a link in this thread.)
First, though, I need to experiment a bit with another Result
-ish adapter. Specifically, Collect for Result
as-is has the limitation that any yielded items before the error are just unretrievably dropped.
I want to at least see if it's possible to write a TResult<B, Item> where Item: Try, B: FromIterator<B::Output>
that stores Result<B, (B, Item::Residual)>
but implements Try<Output=B, Residual=Item::Residual>
. Basically, ?
as-if it were ChangeOutputType<Item, B>
, but allow access to the output elements prior to the residual.
I don't know if we want to actually do it that way, but I'd like to have it for comparison against the simpler one.
Signatures
I did this without rustc to check my work so this is just to sketch the signatures slightly more formally:
fn try_collect<B>(&mut self) ->
ChangeOutputType<Self::Item, B>
where
ChangeOutputType<Self::Item, B>: FromIterator<Self::Item>,
;
fn try_collect<B>(&mut self) ->
TryResult<Self::Item, B>
where
B: FromIterator<<Self::Item as Try>::Output>,
;
enum TryResult<T: Try, B> {
inner: Result<B, (B, T::Residual)>
}
impl<T: Try, B: FromIterator<T::Output>>
Try for TryResult<T, B> {
type Output = B;
type Residual = T::Residual;
fn from_output(output: T::Output) -> Self {
Self { inner: Ok(output) }
}
fn branch(self) -> ControlFlow<B, T::Residual> {
match self.inner {
Ok(output) => ControlFlow::Continue(output),
Err((_, residual)) => ControlFlow::Break(residual),
}
}
}
impl<T: Try, B: FromIterator<T::Output>>
FromResidual for TryResult<T, B> {
fn from_residual(residual: T::Residual) -> Self {
Self { inner: Err((iter::empty().collect(), residual)) }
}
}