use crate::lazy::decoder::{Decoder, HasRange, HasSpan};
use crate::lazy::span::Span;
use crate::result::IonFailure;
use crate::{AnyEncoding, IonEncoding, IonError, IonResult};
use std::fmt::Debug;
use std::ops::Range;
#[derive(Debug, Copy, Clone)]
pub enum RawStreamItem<M: Debug + Copy + Clone, V: Debug + Copy + Clone, E: Debug + Copy + Clone> {
VersionMarker(M),
Value(V),
EExp(E),
EndOfStream(EndPosition),
}
pub type LazyRawStreamItem<'top, D> = RawStreamItem<
<D as Decoder>::VersionMarker<'top>,
<D as Decoder>::Value<'top>,
<D as Decoder>::EExp<'top>,
>;
impl LazyRawStreamItem<'_, AnyEncoding> {
pub fn encoding(&self) -> IonEncoding {
match self {
LazyRawStreamItem::<AnyEncoding>::VersionMarker(m) => m.encoding(),
LazyRawStreamItem::<AnyEncoding>::Value(v) => v.encoding(),
LazyRawStreamItem::<AnyEncoding>::EExp(e) => e.encoding(),
LazyRawStreamItem::<AnyEncoding>::EndOfStream(eos) => eos.encoding(),
}
}
}
impl<
M: Debug + Copy + Clone + HasRange,
V: Debug + Copy + Clone + HasRange,
E: Debug + Copy + Clone + HasRange,
> HasRange for RawStreamItem<M, V, E>
{
fn range(&self) -> Range<usize> {
use RawStreamItem::*;
match self {
VersionMarker(marker) => marker.range(),
Value(value) => value.range(),
EExp(eexp) => eexp.range(),
EndOfStream(eos) => eos.range(),
}
}
}
impl<
'top,
M: Debug + Copy + Clone + HasSpan<'top>,
V: Debug + Copy + Clone + HasSpan<'top>,
E: Debug + Copy + Clone + HasSpan<'top>,
> HasSpan<'top> for RawStreamItem<M, V, E>
{
fn span(&self) -> Span<'top> {
use RawStreamItem::*;
match self {
VersionMarker(marker) => marker.span(),
Value(value) => value.span(),
EExp(eexp) => eexp.span(),
EndOfStream(eos) => eos.span(),
}
}
}
impl<M: Copy + Debug, V: Copy + Debug, E: Copy + Debug> RawStreamItem<M, V, E> {
pub fn version_marker(&self) -> Option<M> {
if let Self::VersionMarker(marker) = self {
Some(*marker)
} else {
None
}
}
pub fn expect_ivm(self) -> IonResult<M> {
self.version_marker()
.ok_or_else(|| IonError::decoding_error(format!("expected IVM, found {self:?}")))
}
pub fn value(&self) -> Option<&V> {
if let Self::Value(value) = self {
Some(value)
} else {
None
}
}
pub fn expect_value(self) -> IonResult<V> {
if let Self::Value(value) = self {
Ok(value)
} else {
IonResult::decoding_error(format!("expected value, found {self:?}"))
}
}
pub fn as_macro_invocation(&self) -> Option<&E> {
if let Self::EExp(m) = self {
Some(m)
} else {
None
}
}
pub fn expect_eexp(self) -> IonResult<E> {
if let Self::EExp(m) = self {
Ok(m)
} else {
IonResult::decoding_error(format!("expected a macro invocation, found {self:?}"))
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct EndPosition {
encoding: IonEncoding,
position: usize,
}
impl EndPosition {
pub(crate) fn new(encoding: IonEncoding, position: usize) -> Self {
Self { encoding, position }
}
pub fn encoding(&self) -> IonEncoding {
self.encoding
}
}
impl HasRange for EndPosition {
fn range(&self) -> Range<usize> {
self.position..self.position
}
}
impl<'top> HasSpan<'top> for EndPosition {
fn span(&self) -> Span<'top> {
Span::with_offset(self.position, &[])
}
}