Skip to content

ion-tests needs a better way to capture encoding context #967

Open
@zslayton

Description

@zslayton

See this comment:

// The Writer is asked to serialize Elements that represent system values.
// In many cases, it will emit a macro table containing macros that are not in its own
// encoding context. For example, this snippet:
//
// (mactab (macro m (v!) v))
//
// will emit a system value that the reader will understand defines macro `m`.
// However, the writer emitting the system value does not have macro `m` in its own
// encoding context. If the test later invokes `m` like this:
//
// (toplevel ('#$:m' 5))
//
// the Writer will raise an error reporting that the test is trying to invoke a
// non-existent macro.
//
// As a workaround, when serializing top-level Elements, the writer does an initial
// serialization pass to load any necessary encoding context changes.
//
// Serialize the data once...
let serialized = v1_1::Text::encode_all(self.elems.as_slice())?;
// ...then read the data, constructing a macro table in the Reader...
let mut reader = Reader::new(AnyEncoding, serialized)?;
while reader.next()?.is_some() {}
let macro_table = reader.macro_table();
if ctx.version() == IonVersion::V1_1 {
// For each macro in the Reader...
for mac in macro_table.iter() {
// ...try to register the macro in the Writer. For simplicity, we skip over
// system macros that are already defined.
let _result = writer.register_macro(&mac);
}
}
// Now that the Writer has the necessary context, it can encode the ProxyElements.
for elem in self.elems.as_slice() {
writer.write(ProxyElement(elem, ctx))?;
}
Ok(())

cc @nirosys

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions