IonReader Associated Trait Bounds
Users generally will work only with IonReader<Item = StreamItem, Symbol = Symbol>, but within the implementation it may be useful to operate generically across different IonReader implementations. E.g., I have an abstraction that works across (or on some subset of):
IonReader<Item = StreamItem, Symbol = Symbol>IonReader<Item = RawStreamItem, Symbol = RawSymbolToken>IonReader<Item = SystemStreamItem, Symbol = Symbol>
Currently, it is awkward to work across this boundary since StreamItem, RawStreamItem, and SystemStreamItem have similar enumerations, but they are not actually related, so one cannot write generically across them.
// note the missing Copy/Clone--that is probably a bug
#[derive(Eq, PartialEq, Debug)]
pub enum StreamItem {
Value(IonType),
Null(IonType),
Nothing,
}
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum RawStreamItem {
VersionMarker(u8, u8),
Value(IonType),
Null(IonType),
Nothing,
}
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum SystemStreamItem {
VersionMarker(u8, u8),
SymbolTableValue(IonType),
SymbolTableNull(IonType),
Value(IonType),
Null(IonType),
Nothing,
}
As we can see, there is structural similarity here. One option might be to have a trait that all IonReader::StreamItem must implement:
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum CommonStreamItem {
/// Something the common interface cannot "see."
/// We could put all the system nested or flattened here if we want...
Other,
Value(IonType),
Null(IonType),
Nothing,
}
pub trait ReaderStreamItem: Debug + Eq + PartialEq + Copy + Clone {
fn as_common(self) -> CommonItem;
}
To get something marginally useful for a common Symbol trait, we could do the following:
pub trait ReaderSymbol {
fn text(&self) -> Option<&str>;
fn local_sid(&self) -> Option<SymbolId>;
}
With the above I can now write:
fn do_something<R, I, S>(reader: &mut R)
where
R: IonReader<Item = I, Symbol = S>,
I: ReaderStreamItem,
S: ReaderSymbol
{
// do some stuff generically on the reader where we don't care about symbols too much
// note that constraining S to Symbol, makes this work only for User/System stream which may
// be desirable...
}