Expand description
Dynamic-dispatching factories for readers with a lifetime.
§Motivation
FuncCodeReader already provides dynamic dispatching of read functions,
but in some uses cases the reader has to reference some data (e.g., readers
based on the same memory buffer). In this case, one would need to create a
dispatching function pointer for each code and each reader because the
lifetime of different readers make the function pointers incompatible.
The trait CodesReaderFactory solves this problem by providing a way to
create a CodesRead with a lifetime that can reference data owned by the
factory. This trait must be implemented by client applications.
At the point, one can create a FactoryFuncCodeReader depending on a
specific CodesReaderFactory. The FactoryFuncCodeReader will store a
function pointer with a generic lifetime that can be downcast to a specific
lifetime. Thus, the function pointer is created just once at the creation of
the FactoryFuncCodeReader, and can be reused to create
FuncCodeReaders with any lifetime using FactoryFuncCodeReader::get.
§Implementation Notes
In principle, we would like to have inside a FactoryFuncCodeReader a
field with type
for<'a> FuncCodeReader<E, CRF::CodesReader<'a>>However, this is not possible in the Rust type system. We can however write the type
for<'a> fn(&mut CRF::CodesReader<'a>) -> Result<u64>This workaround is not perfect as we cannot properly specify the error type:
Result<u64, <CRF::CodesReader<'a> as BitRead<E>>::Error>The compiler here complains that the return type has a lifetime not constrained by the input arguments.
To work around this problem, we could add an otherwise useless associated
type CodesReaderFactory::Error to the CodesReaderFactory trait,
imposing that the error type of CodesReaderFactory::CodesReader is the
same. Unfortunately, this requires that all users of the factory add a where
constraint in which the error type is written explicitly.
To mitigate this problem, we provide instead a helper trait
CodesReaderFactoryHelper that extends CodesReaderFactory; the helper
trait contains an Error associated type and uses higher-rank trait
bounds
to bind the associated type to the error type of the
CodesReaderFactory::CodesReader. The user can implement
CodesReaderFactory on its own types and write trait bounds using
CodesReaderFactoryHelper:
fn test<E: Endianness, CRF: CodesReaderFactoryHelper<E>>(factory: CRF)
{
let reader = factory.new_reader();
// do something with the reader
// CRF::Error is the error type of CRF::CodesReader<'a>
}Structs§
- Factory
Func Code Reader - A newtype depending on a
CodesReaderFactoryand containing a function pointer dispatching the read method for a code.
Traits§
- Codes
Reader Factory - A trait that models a type that can return a
CodesReadthat can reference data owned by the factory. The typical case is a factory that owns the bit stream, and returns aCodesReadthat can read from it. - Codes
Reader Factory Helper - Extension helper trait for
CodesReaderFactory.