So, in the process of trying to make something very, very generic and also remove some offsetting logic out of one trait into another, I came across this problem, and the solution isn’t obvious, but it seems a case where the open error type idea shines very nicely, both ergonomically, and logically:
pub trait Pread<Ctx, E = error::Error, I = usize> : Index<I> + Index<RangeFrom<I>> + MeasureWith<Ctx, Units = I>
where
Ctx: Copy + Default + Debug,
I: Add + Copy + PartialOrd,
{
fn pread<'a, N: TryFromCtx<'a, Ctx, <Self as Index<RangeFrom<I>>>::Output, Error = E>>(&'a self, offset: I) -> result::Result<N, E> where <Self as Index<RangeFrom<I>>>::Output: 'a {
self.pread_with(offset, Ctx::default())
}
fn pread_with<'a, N: TryFromCtx<'a, Ctx, <Self as Index<RangeFrom<I>>>::Output, Error = E>>(&'a self, offset: I, ctx: Ctx) -> result::Result<N, E> where <Self as Index<RangeFrom<I>>>::Output: 'a {
let len = self.measure_with(&ctx);
if offset >= len {
// problem is here, what do i return? the error is/should be generic
panic!("offset >= len")
}
N::try_from_ctx(&self[offset..], ctx)
}
}
If errors were an open type, I would be able to return my custom Error enum, e.g. return Err(BadOffset(offset)) where the panic is, but while still allowing downstream clients/implementors of TryFromCtx to use their own custom errors in TryFromCtx, whose definition for completeness is:
/// Tries to read `Self` from `This` using the context `Ctx`
pub trait TryFromCtx<'a, Ctx: Copy = DefaultCtx, This: ?Sized = [u8]> where Self: 'a + Sized {
type Error;
#[inline]
fn try_from_ctx(from: &'a This, ctx: Ctx) -> Result<Self, Self::Error>;
}
I might be able to do this using dynamic dispatch, but I’m not really an expert there, would require signature changes, and a performance hit that is not acceptable in this case for this crate’s usecases.
Anyway, just came up, and thought of this, so figured I’d post a little pain point.
As I see it, only reasonable solution might seem to be to remove the generic errors, and use explicit error hardcoded into the signature, which kind of sucks 