Skip to content

Commit

Permalink
Working expansion w/o variables
Browse files Browse the repository at this point in the history
  • Loading branch information
zslayton committed Oct 13, 2023
1 parent a176e81 commit 2675d43
Show file tree
Hide file tree
Showing 20 changed files with 1,187 additions and 965 deletions.
2 changes: 1 addition & 1 deletion examples/lazy_read_all_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ mod lazy_reader_example {
Ok(1 + child_count)
}

fn count_sequence_children<'a, 'b>(
fn count_sequence_children<'a, 'b: 'a>(
lazy_sequence: impl Iterator<Item = IonResult<LazyBinaryValue<'a, 'b>>>,
) -> IonResult<usize> {
let mut count = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/ion_data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl<T: Display> Display for IonData<T> {

impl<T: IonEq + IonOrd> PartialOrd for IonData<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(IonOrd::ion_cmp(&self.0, &other.0))
Some(self.cmp(other))
}
}

Expand Down
131 changes: 56 additions & 75 deletions src/lazy/any_encoding.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![allow(non_camel_case_types)]

use std::fmt::Debug;
use std::marker::PhantomData;

use crate::lazy::binary::raw::annotations_iterator::RawBinaryAnnotationsIterator;
use crate::lazy::binary::raw::r#struct::{LazyRawBinaryStruct, RawBinaryStructIterator};
Expand All @@ -13,11 +12,11 @@ use crate::lazy::binary::raw::value::LazyRawBinaryValue;
use crate::lazy::decoder::private::{LazyContainerPrivate, LazyRawValuePrivate};
use crate::lazy::decoder::{
LazyDecoder, LazyRawFieldExpr, LazyRawReader, LazyRawSequence, LazyRawStruct, LazyRawValue,
LazyRawValueExpr, RawArgumentExpr, RawFieldExpr, RawValueExpr,
LazyRawValueExpr, RawFieldExpr, RawValueExpr,
};
use crate::lazy::encoding::{BinaryEncoding_1_0, TextEncoding_1_0, TextEncoding_1_1};
use crate::lazy::expanded::macro_evaluator::{EExpEvaluator, MacroInvocation};
use crate::lazy::expanded::sequence::Environment;
use crate::lazy::expanded::e_expression::EExpression;
use crate::lazy::expanded::macro_evaluator::RawMacroInvocation;
use crate::lazy::expanded::EncodingContext;
use crate::lazy::never::Never;
use crate::lazy::raw_stream_item::RawStreamItem;
Expand All @@ -29,13 +28,14 @@ use crate::lazy::text::raw::sequence::{
};
use crate::lazy::text::raw::v1_1::reader::{
LazyRawTextList_1_1, LazyRawTextSExp_1_1, LazyRawTextStruct_1_1, MacroIdRef,
RawTextListIterator_1_1, RawTextMacroInvocation, RawTextSExpIterator_1_1,
RawTextEExpression_1_1, RawTextListIterator_1_1, RawTextSExpIterator_1_1,
RawTextStructIterator_1_1,
};
use crate::lazy::text::value::{
LazyRawTextValue_1_0, LazyRawTextValue_1_1, RawTextAnnotationsIterator,
};
use crate::{IonResult, IonType, RawSymbolTokenRef};
use crate::result::IonFailure;
use crate::{IonError, IonResult, IonType, RawSymbolTokenRef};

/// An implementation of the `LazyDecoder` trait that can read any encoding of Ion.
#[derive(Debug, Clone, Copy)]
Expand All @@ -51,97 +51,78 @@ impl<'data> LazyDecoder<'data> for AnyEncoding {
type List = LazyRawAnyList<'data>;
type Struct = LazyRawAnyStruct<'data>;
type AnnotationsIterator = RawAnyAnnotationsIterator<'data>;
type MacroInvocation = LazyRawAnyMacroInvocation<'data>;
type RawMacroInvocation = LazyRawAnyEExpression<'data>;
type MacroInvocation<'top> = EExpression<'top, 'data, AnyEncoding> where 'data: 'top;
}

#[derive(Debug, Copy, Clone)]
pub struct LazyRawAnyMacroInvocation<'data> {
encoding: LazyRawAnyMacroInvocationKind<'data>,
pub struct LazyRawAnyEExpression<'data> {
encoding: LazyRawAnyEExpressionKind<'data>,
}

#[derive(Debug, Copy, Clone)]
enum LazyRawAnyMacroInvocationKind<'data> {
enum LazyRawAnyEExpressionKind<'data> {
// Ion 1.0 does not support macro invocations. Having these variants hold an instance of
// `Never` (which cannot be instantiated) informs the compiler that it can eliminate these
// branches in code paths exclusive to v1.0.
Text_1_0(Never),
Binary_1_0(Never),
Text_1_1(RawTextMacroInvocation<'data>),
Text_1_1(RawTextEExpression_1_1<'data>),
}

impl<'data> From<RawTextMacroInvocation<'data>> for LazyRawAnyMacroInvocation<'data> {
fn from(text_invocation: RawTextMacroInvocation<'data>) -> Self {
LazyRawAnyMacroInvocation {
encoding: LazyRawAnyMacroInvocationKind::Text_1_1(text_invocation),
impl<'data> From<RawTextEExpression_1_1<'data>> for LazyRawAnyEExpression<'data> {
fn from(text_invocation: RawTextEExpression_1_1<'data>) -> Self {
LazyRawAnyEExpression {
encoding: LazyRawAnyEExpressionKind::Text_1_1(text_invocation),
}
}
}

impl<'data> MacroInvocation<'data, AnyEncoding> for LazyRawAnyMacroInvocation<'data> {
type ArgumentExpr = LazyRawValueExpr<'data, AnyEncoding>;
type ArgumentsIterator = LazyRawAnyMacroArgsIterator<'data>;
type RawArgumentsIterator = LazyRawAnyMacroRawArgsIterator<'data>;

type TransientEvaluator<'context> =
EExpEvaluator<'context, 'data, AnyEncoding> where Self: 'context, 'data: 'context;
impl<'data> RawMacroInvocation<'data, AnyEncoding> for LazyRawAnyEExpression<'data> {
type RawArgumentsIterator<'a> = LazyRawAnyMacroArgsIterator<'data> where Self: 'a;
type MacroInvocation<'top> = EExpression<'top, 'data, AnyEncoding> where 'data: 'top;

fn id(&self) -> MacroIdRef<'_> {
fn id(&self) -> MacroIdRef<'data> {
match self.encoding {
LazyRawAnyMacroInvocationKind::Text_1_0(_) => unreachable!("macro in text Ion 1.0"),
LazyRawAnyMacroInvocationKind::Binary_1_0(_) => unreachable!("macro in binary Ion 1.0"),
LazyRawAnyMacroInvocationKind::Text_1_1(ref m) => m.id(),
LazyRawAnyEExpressionKind::Text_1_0(_) => unreachable!("macro in text Ion 1.0"),
LazyRawAnyEExpressionKind::Binary_1_0(_) => unreachable!("macro in binary Ion 1.0"),
LazyRawAnyEExpressionKind::Text_1_1(ref m) => m.id(),
}
}

fn arguments(&self) -> Self::ArgumentsIterator {
fn raw_arguments(&self) -> Self::RawArgumentsIterator<'_> {
match self.encoding {
LazyRawAnyMacroInvocationKind::Text_1_0(_) => unreachable!("macro in text Ion 1.0"),
LazyRawAnyMacroInvocationKind::Binary_1_0(_) => unreachable!("macro in binary Ion 1.0"),
LazyRawAnyMacroInvocationKind::Text_1_1(m) => LazyRawAnyMacroArgsIterator {
encoding: LazyRawAnyMacroArgsIteratorKind::Text_1_1(m.arguments()),
LazyRawAnyEExpressionKind::Text_1_0(_) => unreachable!("macro in text Ion 1.0"),
LazyRawAnyEExpressionKind::Binary_1_0(_) => unreachable!("macro in binary Ion 1.0"),
LazyRawAnyEExpressionKind::Text_1_1(m) => LazyRawAnyMacroArgsIterator {
encoding: LazyRawAnyMacroArgsIteratorKind::Text_1_1(m.raw_arguments()),
},
}
}

fn raw_arguments(&self) -> Self::RawArgumentsIterator {
todo!()
}

fn make_transient_evaluator<'context>(
context: EncodingContext<'context>,
_environment: Environment<'context, 'data, AnyEncoding>,
) -> Self::TransientEvaluator<'context>
fn resolve<'top>(self, context: EncodingContext<'top>) -> IonResult<Self::MacroInvocation<'top>>
where
'data: 'context,
Self: 'context,
'data: 'top,
{
// E-expressions do not have an environment, so we ignore that parameter.
Self::TransientEvaluator::new(context)
}
}

pub enum LazyRawAnyMacroRawArgsIteratorKind<'data> {
TODO(PhantomData<&'data ()>),
}

pub struct LazyRawAnyMacroRawArgsIterator<'data> {
encoding: LazyRawAnyMacroRawArgsIteratorKind<'data>,
}

impl<'data> Iterator for LazyRawAnyMacroRawArgsIterator<'data> {
type Item = RawArgumentExpr<'data, AnyEncoding>;

fn next(&mut self) -> Option<Self::Item> {
todo!()
let invoked_macro = context
.macro_table
.macro_with_id(self.id())
.ok_or_else(|| {
IonError::decoding_error(format!("unrecognized macro ID {:?}", self.id()))
})?;
Ok(EExpression {
context,
raw_invocation: self,
invoked_macro,
})
}
}

pub enum LazyRawAnyMacroArgsIteratorKind<'data> {
Text_1_1(
<RawTextMacroInvocation<'data> as MacroInvocation<
<RawTextEExpression_1_1<'data> as RawMacroInvocation<
'data,
TextEncoding_1_1,
>>::ArgumentsIterator,
>>::RawArgumentsIterator<'data>,
),
}
pub struct LazyRawAnyMacroArgsIterator<'data> {
Expand All @@ -157,11 +138,11 @@ impl<'data> Iterator for LazyRawAnyMacroArgsIterator<'data> {
Some(Ok(RawValueExpr::ValueLiteral(value))) => {
Some(Ok(RawValueExpr::ValueLiteral(LazyRawAnyValue::from(value))))
}
Some(Ok(RawValueExpr::MacroInvocation(invocation))) => Some(Ok(
RawValueExpr::MacroInvocation(LazyRawAnyMacroInvocation {
encoding: LazyRawAnyMacroInvocationKind::Text_1_1(invocation),
}),
)),
Some(Ok(RawValueExpr::MacroInvocation(invocation))) => {
Some(Ok(RawValueExpr::MacroInvocation(LazyRawAnyEExpression {
encoding: LazyRawAnyEExpressionKind::Text_1_1(invocation),
})))
}
Some(Err(e)) => Some(Err(e)),
None => None,
},
Expand Down Expand Up @@ -259,8 +240,8 @@ impl<'data> From<LazyRawValueExpr<'data, TextEncoding_1_0>>
match value {
RawValueExpr::ValueLiteral(v) => RawValueExpr::ValueLiteral(v.into()),
RawValueExpr::MacroInvocation(m) => {
let invocation = LazyRawAnyMacroInvocation {
encoding: LazyRawAnyMacroInvocationKind::Text_1_0(m),
let invocation = LazyRawAnyEExpression {
encoding: LazyRawAnyEExpressionKind::Text_1_0(m),
};
RawValueExpr::MacroInvocation(invocation)
}
Expand All @@ -275,8 +256,8 @@ impl<'data> From<LazyRawValueExpr<'data, BinaryEncoding_1_0>>
match value {
RawValueExpr::ValueLiteral(v) => RawValueExpr::ValueLiteral(v.into()),
RawValueExpr::MacroInvocation(m) => {
let invocation = LazyRawAnyMacroInvocation {
encoding: LazyRawAnyMacroInvocationKind::Binary_1_0(m),
let invocation = LazyRawAnyEExpression {
encoding: LazyRawAnyEExpressionKind::Binary_1_0(m),
};
RawValueExpr::MacroInvocation(invocation)
}
Expand All @@ -291,8 +272,8 @@ impl<'data> From<LazyRawValueExpr<'data, TextEncoding_1_1>>
match value {
RawValueExpr::ValueLiteral(v) => RawValueExpr::ValueLiteral(v.into()),
RawValueExpr::MacroInvocation(m) => {
let invocation = LazyRawAnyMacroInvocation {
encoding: LazyRawAnyMacroInvocationKind::Text_1_1(m),
let invocation = LazyRawAnyEExpression {
encoding: LazyRawAnyEExpressionKind::Text_1_1(m),
};
RawValueExpr::MacroInvocation(invocation)
}
Expand Down Expand Up @@ -401,8 +382,8 @@ impl<'data> From<RawStreamItem<'data, TextEncoding_1_1>> for RawStreamItem<'data
}
RawStreamItem::Value(value) => RawStreamItem::Value(value.into()),
RawStreamItem::EExpression(invocation) => {
RawStreamItem::EExpression(LazyRawAnyMacroInvocation {
encoding: LazyRawAnyMacroInvocationKind::Text_1_1(invocation),
RawStreamItem::EExpression(LazyRawAnyEExpression {
encoding: LazyRawAnyEExpressionKind::Text_1_1(invocation),
})
}
RawStreamItem::EndOfStream => RawStreamItem::EndOfStream,
Expand Down
71 changes: 26 additions & 45 deletions src/lazy/decoder.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
use std::fmt::Debug;

use crate::lazy::encoding::TextEncoding_1_1;
use crate::lazy::expanded::macro_evaluator::{EExpEvaluator, MacroInvocation};
use crate::lazy::expanded::sequence::Environment;
use crate::lazy::expanded::template::TemplateMacroArgExpr;
use crate::lazy::expanded::e_expression::TextEExpression_1_1;
use crate::lazy::expanded::macro_evaluator::{MacroInvocation, RawMacroInvocation};
use crate::lazy::expanded::EncodingContext;
use crate::lazy::raw_stream_item::RawStreamItem;
use crate::lazy::raw_value_ref::RawValueRef;
use crate::lazy::text::raw::v1_1::reader::{
MacroIdRef, RawTextMacroInvocation, RawTextSExpIterator_1_1,
MacroIdRef, RawTextEExpression_1_1, RawTextSExpIterator_1_1,
};
use crate::result::IonFailure;
use crate::{IonResult, IonType, RawSymbolTokenRef};
use crate::{IonError, IonResult, IonType, RawSymbolTokenRef};

/// A family of types that collectively comprise the lazy reader API for an Ion serialization
/// format. These types operate at the 'raw' level; they do not attempt to resolve symbols
Expand All @@ -32,7 +31,10 @@ pub trait LazyDecoder<'data>: 'static + Sized + Debug + Clone + Copy {
/// An iterator over the annotations on the input stream's values.
type AnnotationsIterator: Iterator<Item = IonResult<RawSymbolTokenRef<'data>>>;
/// An e-expression invoking a macro. (Ion 1.1+)
type MacroInvocation: MacroInvocation<'data, Self>;
type RawMacroInvocation: RawMacroInvocation<'data, Self>;
type MacroInvocation<'top>: MacroInvocation<'top, 'data, Self>
where
'data: 'top;
}

/// An expression found in value position in either serialized Ion or a template.
Expand Down Expand Up @@ -61,7 +63,7 @@ pub enum RawValueExpr<V, M> {
/// For a version of this type that is not constrained to a particular encoding, see
/// [`RawValueExpr`].
pub type LazyRawValueExpr<'data, D> =
RawValueExpr<<D as LazyDecoder<'data>>::Value, <D as LazyDecoder<'data>>::MacroInvocation>;
RawValueExpr<<D as LazyDecoder<'data>>::Value, <D as LazyDecoder<'data>>::RawMacroInvocation>;

impl<V: Debug, M: Debug> RawValueExpr<V, M> {
pub fn expect_value(self) -> IonResult<V> {
Expand All @@ -84,24 +86,6 @@ impl<V: Debug, M: Debug> RawValueExpr<V, M> {
}
}

#[derive(Copy, Clone, Debug)]
pub enum RawArgumentExpr<'data, D: LazyDecoder<'data>> {
StreamExpr(LazyRawValueExpr<'data, D>),
TemplateExpr(TemplateMacroArgExpr),
}

impl<'data, D: LazyDecoder<'data>> From<LazyRawValueExpr<'data, D>> for RawArgumentExpr<'data, D> {
fn from(stream_value_expr: LazyRawValueExpr<'data, D>) -> Self {
RawArgumentExpr::StreamExpr(stream_value_expr)
}
}

impl<'data, D: LazyDecoder<'data>> From<TemplateMacroArgExpr> for RawArgumentExpr<'data, D> {
fn from(template_value_expr: TemplateMacroArgExpr) -> Self {
RawArgumentExpr::TemplateExpr(template_value_expr)
}
}

/// An item found in field position within a struct.
/// This item may be:
/// * a name/value pair (as it is in Ion 1.0)
Expand All @@ -122,7 +106,7 @@ pub enum RawFieldExpr<'name, V, M> {
pub type LazyRawFieldExpr<'data, D> = RawFieldExpr<
'data,
<D as LazyDecoder<'data>>::Value,
<D as LazyDecoder<'data>>::MacroInvocation,
<D as LazyDecoder<'data>>::RawMacroInvocation,
>;

impl<'name, V: Debug, M: Debug> RawFieldExpr<'name, V, M> {
Expand Down Expand Up @@ -196,35 +180,32 @@ pub(crate) mod private {
}
}

impl<'data> MacroInvocation<'data, TextEncoding_1_1> for RawTextMacroInvocation<'data> {
type ArgumentExpr = LazyRawValueExpr<'data, TextEncoding_1_1>;
type ArgumentsIterator = RawTextSExpIterator_1_1<'data>;
type RawArgumentsIterator = Box<dyn Iterator<Item = RawArgumentExpr<'data, TextEncoding_1_1>>>;
// TODO: Everything should use LazyRawValueExpr in the RMI impl?

type TransientEvaluator<'context> =
EExpEvaluator<'context, 'data, TextEncoding_1_1> where Self: 'context, 'data: 'context;
impl<'data> RawMacroInvocation<'data, TextEncoding_1_1> for RawTextEExpression_1_1<'data> {
type RawArgumentsIterator<'a> = RawTextSExpIterator_1_1<'data> where Self: 'a;

fn id(&self) -> MacroIdRef {
type MacroInvocation<'top> = TextEExpression_1_1<'top, 'data> where 'data: 'top;

fn id(&self) -> MacroIdRef<'data> {
self.id
}

fn arguments(&self) -> Self::ArgumentsIterator {
fn raw_arguments(&self) -> Self::RawArgumentsIterator<'_> {
RawTextSExpIterator_1_1::new(self.arguments_bytes())
}

fn raw_arguments(&self) -> Self::RawArgumentsIterator {
todo!()
}

fn make_transient_evaluator<'context>(
context: EncodingContext<'context>,
_environment: Environment<'context, 'data, TextEncoding_1_1>,
) -> Self::TransientEvaluator<'context>
fn resolve<'top>(self, context: EncodingContext<'top>) -> IonResult<Self::MacroInvocation<'top>>
where
Self: 'context,
'data: 'top,
{
// E-expressions do not have an environment, so we ignore that parameter.
Self::TransientEvaluator::new(context)
let invoked_macro = context
.macro_table
.macro_with_id(self.id())
.ok_or_else(|| {
IonError::decoding_error(format!("unrecognized macro ID {:?}", self.id()))
})?;
Ok(TextEExpression_1_1::new(context, self, invoked_macro))
}
}

Expand Down
Loading

0 comments on commit 2675d43

Please sign in to comment.