Trait push_decode::Decoder
source · pub trait Decoder: Sized {
type Value;
type Error;
// Required methods
fn decode_chunk(&mut self, bytes: &mut &[u8]) -> Result<(), Self::Error>;
fn end(self) -> Result<Self::Value, Self::Error>;
// Provided methods
fn bytes_received(&mut self, bytes: &[u8]) -> Result<usize, Self::Error> { ... }
fn then<R: Decoder, F: FnOnce(Self::Value) -> R>(
self,
fun: F
) -> Then<Self, R, F> { ... }
fn then_try<E, R: Decoder, F: FnOnce(Self::Value) -> Result<R, E>>(
self,
fun: F
) -> ThenTry<E, Self, R, F>
where E: From<Self::Error> + From<R::Error> { ... }
fn chain<D: Decoder>(self, following: D) -> Chain<Self, D> { ... }
fn take(&mut self) -> Result<Self::Value, Self::Error>
where Self: Default { ... }
fn sub_decode<E, F: FnMut(Self::Error) -> E>(
&mut self,
bytes: &mut &[u8],
map_err: F
) -> ControlFlow<Result<(), E>, Self::Value>
where Self: Default { ... }
fn wrap_sub_decode<F: FnOnce() -> ControlFlow<Result<(), Self::Error>, Infallible>>(
f: F
) -> Result<(), Self::Error> { ... }
}Expand description
Represents types responsible for decoding bytes pushed into it.
The types implementing this trait act like state machines (similar to futures) but instead of pulling data from some internal source they receive it in method calls. So they are actually much closer to the traditional state machines than futures.
Required Associated Types§
Required Methods§
sourcefn decode_chunk(&mut self, bytes: &mut &[u8]) -> Result<(), Self::Error>
fn decode_chunk(&mut self, bytes: &mut &[u8]) -> Result<(), Self::Error>
Processes nex chunk of bytes and updates the cursor.
The decoder has to processes the chunk of bytes performing validation and transformation.
If the bytes are valid the slice is updated to point to unread part. Thus if the slice is non-epty after this method returns the decoder ended decoding.
Errors
An error is returned in case the bytes are invalid. The validity is defined by the implementor.
No error may be returned if the number of bytes passed is not sufficient to decode the value - the remaining bytes will be passed in the following call(s) of this method.
sourcefn end(self) -> Result<Self::Value, Self::Error>
fn end(self) -> Result<Self::Value, Self::Error>
Called when decoding has ended or there are no more bytes.
The decoder must validate the bytes passed in so far if it didn’t do so yet and return the decoded value or an error if the bytes were invalid.
Errors
This returns an error if the bytes passed so far are invalid as defined by the decoder. This commonly happens if the byte stream ended unexpectedly.
Provided Methods§
sourcefn bytes_received(&mut self, bytes: &[u8]) -> Result<usize, Self::Error>
fn bytes_received(&mut self, bytes: &[u8]) -> Result<usize, Self::Error>
Processes nex chunk of bytes without updating the cursor.
This method is usually more convenient for the top-level callers which are receiving bytes
from buffered readers. Instead of modifying the slice this returns the number of bytes
consumed which can be passed to the consume method of a buffered reader.
sourcefn then<R: Decoder, F: FnOnce(Self::Value) -> R>(
self,
fun: F
) -> Then<Self, R, F>
fn then<R: Decoder, F: FnOnce(Self::Value) -> R>( self, fun: F ) -> Then<Self, R, F>
Chains another decoder after this one finishes such that the value of this one is used to initialize the next one.
sourcefn then_try<E, R: Decoder, F: FnOnce(Self::Value) -> Result<R, E>>(
self,
fun: F
) -> ThenTry<E, Self, R, F>
fn then_try<E, R: Decoder, F: FnOnce(Self::Value) -> Result<R, E>>( self, fun: F ) -> ThenTry<E, Self, R, F>
Chains another decoder after this one finishes such that the value of this one is used to initialize the next one.
Unlike then this combinator may also return an error and convert the errors into a custom
one.
sourcefn chain<D: Decoder>(self, following: D) -> Chain<Self, D>
fn chain<D: Decoder>(self, following: D) -> Chain<Self, D>
Chains another decoder after this one to decode two values.
sourcefn take(&mut self) -> Result<Self::Value, Self::Error>where
Self: Default,
fn take(&mut self) -> Result<Self::Value, Self::Error>where
Self: Default,
Resets the decoder returning the decoded value.
sourcefn sub_decode<E, F: FnMut(Self::Error) -> E>(
&mut self,
bytes: &mut &[u8],
map_err: F
) -> ControlFlow<Result<(), E>, Self::Value>where
Self: Default,
fn sub_decode<E, F: FnMut(Self::Error) -> E>(
&mut self,
bytes: &mut &[u8],
map_err: F
) -> ControlFlow<Result<(), E>, Self::Value>where
Self: Default,
Decodes a value from lower-level decoder.
When multiple decoders are chained one after another in a large state machine this method
can simplify delegation of decoding to the underlying decoder. You can wrap decoding in a
closure passed to Self::wrap_sub_decode and then just call sub_decode()? at the
beginning of each decoding state and continue working with the returned value.
The method also accepts a function (closure) to convert the errors since using map_err
would be annoying because of double wrapping. In case no conversion is desired simply pass
in core::convert::identity.
Note that this requires the Default trait because it resets the decoder every time a
value is decoded. Apart from this resolving borrowing issues it also allows easily decoding
a stream of value in a loop. If you need to work with decoders that require a value (e.g.
VecDecoder) it is recommended to create a specialized decoder that
will decode both (e.g. using Then) and call sub_deode on
that.
You may notice this looks a lot like await and in principle it is very similar. The
differences are:
awaitalso implements the state machine usingFuturetrait. This doesn’t. TheFuture::pollmethod would have to have another argument for us to be able to use it.- This returns
ControlFlowinstead ofPoll<Result>to make it return in case of “not ready” as well. TheTryimplementation onPollonly returns onErr, never onPending. This is important for ergonomics. - While it could be argued the type is morally
Poll<Error>this one doesn’t implementTryeither so it’s unsuitable for the purpose.
sourcefn wrap_sub_decode<F: FnOnce() -> ControlFlow<Result<(), Self::Error>, Infallible>>(
f: F
) -> Result<(), Self::Error>
fn wrap_sub_decode<F: FnOnce() -> ControlFlow<Result<(), Self::Error>, Infallible>>( f: F ) -> Result<(), Self::Error>
Helper for using sub_decode.
This can be used together with sub_decode on sub-decoders to make
decoding easier. It helps with type inference and converts ControlFlow into Result.
Note that this doesn’t allow returning ControlFlow::Continue as that wouldn’t make sense.
It is recommended to just return ControlFlow::Break with the result returned from
decode_chunk of the last decoder.
Object Safety§
Implementors§
source§impl Decoder for ByteVecDecoder
Available on crate feature alloc only.
impl Decoder for ByteVecDecoder
alloc only.source§impl Decoder for Utf8StringDecoder
Available on crate feature alloc only.
impl Decoder for Utf8StringDecoder
alloc only.