Unparsers

This commit is contained in:
Tony Garnock-Jones 2021-06-29 16:54:29 +02:00
parent 5c2d12971d
commit aa1c983acc
9 changed files with 653 additions and 53 deletions

View File

@ -0,0 +1,11 @@
use crate::*;
use crate::syntax::block::Item;
use crate::syntax::block::constructors::*;
pub fn push_let(body: &mut Vec<Item>, name: Item, expr: Item) {
body.push(item(seq!["let ", name, " = ", expr, ";"]))
}
pub fn push_let_mut(body: &mut Vec<Item>, name: Item, expr: Item) {
body.push(item(seq!["let mut ", name, " = ", expr, ";"]))
}

View File

@ -13,7 +13,6 @@ pub struct ModuleContext {
pub struct FunctionContext<'a> {
pub m: &'a mut ModuleContext,
pub temp_counter: usize,
pub temps: Map<types::TDefinition, Vec<String>>,
pub captures: Vec<Capture>,
}
@ -52,7 +51,6 @@ impl<'a> FunctionContext<'a> {
FunctionContext {
m: m,
temp_counter: 0,
temps: Map::new(),
captures: Vec::new(),
}
}
@ -65,9 +63,27 @@ impl<'a> FunctionContext<'a> {
})
}
pub fn lookup_capture(&self, field_name: &str) -> &Capture {
for c in &self.captures {
if c.field_name == field_name {
return c;
}
}
panic!("No capture for field {:?} available", field_name)
}
pub fn gentempname(&mut self) -> String {
let i = self.temp_counter;
self.temp_counter += 1;
format!("_tmp{}", i)
}
pub fn branch<R, F: FnOnce(&mut Self) -> R>(&mut self, f: F) -> R {
let saved_temp_counter = self.temp_counter;
let saved_capture_count = self.captures.len();
let result = f(self);
self.temp_counter = saved_temp_counter;
self.captures.truncate(saved_capture_count);
result
}
}

View File

@ -2,6 +2,8 @@ pub mod types;
pub mod names;
pub mod context;
pub mod parsers;
pub mod unparsers;
pub mod codegen;
use std::path::PathBuf;
use preserves::value::Map;
@ -40,6 +42,7 @@ pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
for (n, d) in &v.definitions.0 {
m.define_type(item(types::render_definition_type(n, &types::definition_type(d))));
parsers::gen_definition_parser(&mut m, n, d);
unparsers::gen_definition_unparser(&mut m, n, d);
}
//---------------------------------------------------------------------------

View File

@ -1,10 +1,12 @@
use crate::*;
use crate::metaschema::*;
use crate::syntax::block::Item;
use crate::syntax::block::constructors::*;
use super::codegen::*;
use super::context::{ModuleContext, FunctionContext};
use super::names;
use super::types::*;
use crate::metaschema::*;
use super::context::{ModuleContext, FunctionContext};
pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
m.define_function(
@ -23,7 +25,7 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
let mut body = Vec::new();
let dest = pattern_parser(&mut ctxt, pat, "value", None, &mut body);
let dest = dest.as_ref().map(String::as_str);
construct(&ctxt, ctorname, false, &TDefinition::Simple(pattern_type(pat)), dest, &mut body);
construct(&ctxt, ctorname, false, &pattern_type(pat), dest, &mut body);
item(seq!["fn ", fname.clone(), "(value: &preserves::value::IOValue) -> ",
"std::result::Result<", names::render_constructor(n), ", ()> ",
block(body)])
@ -35,15 +37,15 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
Definition::And { pattern_0, pattern_1, pattern_n } => {
let mut ps = vec![&**pattern_0, &**pattern_1];
ps.extend(pattern_n);
for e in ps {
for e in &ps {
named_pattern_parser(&mut ctxt, e, "value", None, &mut body);
}
construct(&ctxt, item(names::render_constructor(n)), true, &definition_type(d), None, &mut body);
construct(&ctxt, item(names::render_constructor(n)), true, &record_type(&ps), None, &mut body);
}
Definition::Pattern(p) => {
let dest = pattern_parser(&mut ctxt, p, "value", None, &mut body);
let dest = dest.as_ref().map(String::as_str);
construct(&ctxt, item(names::render_constructor(n)), true, &definition_type(d), dest, &mut body);
construct(&ctxt, item(names::render_constructor(n)), true, &pattern_type(p), dest, &mut body);
}
}
@ -60,16 +62,16 @@ fn construct(
ctxt: &FunctionContext,
ctorname: Item,
is_struct: bool,
ty: &TDefinition,
ty: &TSimple,
dest: Option<&str>,
body: &mut Vec<Item>,
) {
match ty {
TDefinition::Simple(TSimple::Field(TField::Unit)) =>
TSimple::Field(TField::Unit) =>
body.push(item(seq!["Ok(", ctorname, ")"])),
TDefinition::Simple(TSimple::Field(fieldty)) =>
TSimple::Field(fieldty) =>
body.push(item(seq!["Ok(", ctorname, parens![store_wrap(is_struct, fieldty, dest.unwrap())], ")"])),
_ =>
TSimple::Record(_) =>
body.push(item(seq!["Ok(", ctorname, " ", braces(
ctxt.captures.iter().map(
|c| item(seq![c.field_name.clone(), ": ", store_wrap(is_struct, &c.ty, &c.source_expr)])).collect()),
@ -93,14 +95,6 @@ fn store_wrap(is_struct: bool, ty: &TField, expr: &str) -> String {
}
}
fn push_let(body: &mut Vec<Item>, name: &str, expr: Item) {
body.push(item(seq!["let ", name.to_owned(), " = ", expr, ";"]))
}
fn push_let_mut(body: &mut Vec<Item>, name: &str, expr: Item) {
body.push(item(seq!["let mut ", name.to_owned(), " = ", expr, ";"]))
}
fn simple_pattern_parser(
ctxt: &mut FunctionContext,
p: &SimplePattern,
@ -111,7 +105,7 @@ fn simple_pattern_parser(
let dest = ctxt.gentempname();
match p {
SimplePattern::Any => {
push_let(body, &dest, item(src.to_owned()));
push_let(body, item(dest.to_owned()), item(src.to_owned()));
dest
},
SimplePattern::Atom { atom_kind: k } => {
@ -124,17 +118,17 @@ fn simple_pattern_parser(
AtomKind::ByteString => "to_bytestring",
AtomKind::Symbol => "to_symbol",
};
push_let(body, &dest, item(seq![src.to_owned(), ".value().", converter, "().map_err(|_| ())?"]));
push_let(body, item(dest.to_owned()), item(seq![src.to_owned(), ".value().", converter, "().map_err(|_| ())?"]));
dest
},
SimplePattern::Embedded { .. } => {
push_let(body, &dest, item(seq![src.to_owned(), ".value().to_embedded().map_err(|_| ())?"]));
push_let(body, item(dest.to_owned()), item(seq![src.to_owned(), ".value().to_embedded().map_err(|_| ())?"]));
dest
},
SimplePattern::Lit { value } => {
body.push(item(seq!["if ", src.to_owned(), " != ", ctxt.m.define_literal(value),
" { return Err(()); }"]));
push_let(body, &dest, item("()"));
push_let(body, item(dest.to_owned()), item("()"));
dest
},
SimplePattern::Seqof { pattern } => {
@ -144,7 +138,7 @@ fn simple_pattern_parser(
let item_dest = simple_pattern_parser(ctxt, pattern, &tmp, None, &mut inner);
inner.push(item(seq![dest.to_owned(), ".push(",
store_wrap(true, &field_type(pattern), &item_dest), ");"]));
push_let_mut(body, &dest, item("std::vec::Vec::new()"));
push_let_mut(body, item(dest.to_owned()), item("std::vec::Vec::new()"));
body.push(item(seq!["for ", tmp.to_owned(),
" in &", src.to_owned(), brackets![seq![n.to_string() , ".."]],
" ", block(inner)]));
@ -156,7 +150,7 @@ fn simple_pattern_parser(
let item_dest = simple_pattern_parser(ctxt, pattern, &tmp, None, &mut inner);
inner.push(item(seq![dest.to_owned(), ".insert(",
store_wrap(true, &field_type(pattern), &item_dest), ");"]));
push_let_mut(body, &dest, item("preserves::value::Set::new()"));
push_let_mut(body, item(dest.to_owned()), item("preserves::value::Set::new()"));
body.push(item(seq!["for ", tmp.to_owned(),
" in ", src.to_owned(), ".value().to_set().map_err(|_| ())?",
" ", block(inner)]));
@ -172,7 +166,7 @@ fn simple_pattern_parser(
dest.to_owned(), ".insert(",
store_wrap(true, &field_type(key), &key_dest), ", ",
store_wrap(true, &field_type(value), &value_dest), ");"]));
push_let_mut(body, &dest, item("preserves::value::Map::new()"));
push_let_mut(body, item(dest.to_owned()), item("preserves::value::Map::new()"));
body.push(item(seq!["for (", tmp_key.to_owned(), ", ", tmp_value.to_owned(), ")",
" in ", src.to_owned(), ".value().to_dictionary().map_err(|_| ())?",
" ", block(inner)]));
@ -183,9 +177,9 @@ fn simple_pattern_parser(
let mut mp = module.clone();
mp.push(name.to_owned());
let tf = name![names::render_ref(mp), "try_from"];
push_let(body, &dest, item(seq![tf,
parens![src.to_owned()],
"?"]));
push_let(body,
item(dest.to_owned()),
item(seq![tf, parens![src.to_owned()], "?"]));
dest
},
}
@ -201,7 +195,9 @@ fn sequenceify(
Some(n) => (src.to_owned(), n),
None => {
let tmp = ctxt.gentempname();
push_let(body, &tmp, item(seq![src.to_owned(), ".value().to_sequence().map_err(|_| ())?"]));
push_let(body,
item(tmp.to_owned()),
item(seq![src.to_owned(), ".value().to_sequence().map_err(|_| ())?"]));
(tmp, 0)
}
}
@ -257,7 +253,7 @@ fn pattern_parser(
match &**c {
CompoundPattern::Rec { label, fields } => {
let rtmp = ctxt.gentempname();
push_let(body, &rtmp, item(seq![src.to_owned(), ".value().to_record(None).map_err(|_| ())?"]));
push_let(body, item(rtmp.to_owned()), item(seq![src.to_owned(), ".value().to_record(None).map_err(|_| ())?"]));
named_pattern_parser(ctxt, &**label, &format!("{}.label()", rtmp), None, body);
named_pattern_parser(ctxt, &**fields, &format!("{}.fields()", rtmp), Some(0), body);
},
@ -268,14 +264,14 @@ fn pattern_parser(
CompoundPattern::TuplePrefix { fixed, variable } => {
let (src, n) = sequenceify(ctxt, src, sequence_base, body);
fixed_sequence_parser(ctxt, n, fixed, &src, body);
named_pattern_parser(ctxt, &promote(&**variable), &src, Some(n + fixed.len()), body);
named_pattern_parser(ctxt, &promote(variable), &src, Some(n + fixed.len()), body);
},
CompoundPattern::Dict { entries } => {
let dtmp = ctxt.gentempname();
push_let(body, &dtmp, item(seq![src.to_owned(), ".value().to_dictionary().map_err(|_| ())?"]));
push_let(body, item(dtmp.to_owned()), item(seq![src.to_owned(), ".value().to_dictionary().map_err(|_| ())?"]));
for (key_lit, value_pat) in entries.0.iter() {
let vtmp = ctxt.gentempname();
push_let(body, &vtmp, item(seq![
push_let(body, item(vtmp.to_owned()), item(seq![
dtmp.to_owned(), ".get", parens![ctxt.m.define_literal(key_lit)],
".ok_or(())?"]));
named_pattern_parser(ctxt, &promote(value_pat), &vtmp, None, body);

View File

@ -31,24 +31,39 @@ pub struct TRecord(pub Vec<(String, TField)>);
pub fn definition_type(d: &Definition) -> TDefinition {
match d {
Definition::Or { pattern_0, pattern_1, pattern_n } => {
let mut entries = Vec::new();
entries.push((pattern_0.variant_label.to_owned(), pattern_type(&pattern_0.pattern)));
entries.push((pattern_1.variant_label.to_owned(), pattern_type(&pattern_1.pattern)));
for e in pattern_n {
entries.push((e.variant_label.to_owned(), pattern_type(&e.pattern)));
}
TDefinition::Union(entries)
},
Definition::And { pattern_0, pattern_1, pattern_n } => {
let mut arms = vec![&**pattern_0, &**pattern_1];
arms.extend(pattern_n);
TDefinition::Simple(record_type(&arms))
},
Definition::Pattern(p) => TDefinition::Simple(pattern_type(p)),
Definition::Or { pattern_0, pattern_1, pattern_n } =>
TDefinition::Union(or_definition_type(pattern_0, pattern_1, pattern_n)),
Definition::And { pattern_0, pattern_1, pattern_n } =>
TDefinition::Simple(and_definition_type(pattern_0, pattern_1, pattern_n)),
Definition::Pattern(p) =>
TDefinition::Simple(pattern_type(p)),
}
}
pub fn or_definition_type(
p0: &NamedAlternative,
p1: &NamedAlternative,
pn: &Vec<NamedAlternative>,
) -> Vec<(String, TSimple)> {
let mut entries = Vec::new();
entries.push((p0.variant_label.to_owned(), pattern_type(&p0.pattern)));
entries.push((p1.variant_label.to_owned(), pattern_type(&p1.pattern)));
for e in pn {
entries.push((e.variant_label.to_owned(), pattern_type(&e.pattern)));
}
entries
}
pub fn and_definition_type(
p0: &NamedPattern,
p1: &NamedPattern,
pn: &Vec<NamedPattern>,
) -> TSimple {
let mut arms = vec![p0, p1];
arms.extend(pn);
record_type(&arms)
}
pub fn pattern_type(p: &Pattern) -> TSimple {
match p {
Pattern::SimplePattern(p) =>

View File

@ -0,0 +1,287 @@
use crate::*;
use crate::metaschema::*;
use crate::syntax::block::constructors::*;
use crate::syntax::block::{Emittable, Item};
use std::cell::Cell;
use std::rc::Rc;
use super::codegen::*;
use super::context::{ModuleContext, FunctionContext};
use super::names;
use super::types::*;
type ValueSource = Option<String>;
#[derive(Clone)]
struct FieldsSink {
finish: Item,
vec_expr: Item,
body: Vec<Item>,
}
#[derive(Clone)]
enum ValueSink {
Normal,
Fields(Rc<Cell<Option<FieldsSink>>>),
}
impl std::fmt::Debug for ValueSink {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
match self {
ValueSink::Normal => write!(f, "ValueSink::Normal"),
ValueSink::Fields(_) => write!(f, "ValueSink::Normal"),
}
}
}
#[derive(Debug)]
struct ValueContext {
src: ValueSource,
sink: ValueSink,
is_struct: bool,
}
fn normal_none(is_struct: bool) -> ValueContext {
ValueContext { src: None, sink: ValueSink::Normal, is_struct: is_struct }
}
fn normal_src(src: String, is_struct: bool) -> ValueContext {
ValueContext { src: Some(src), sink: ValueSink::Normal, is_struct: is_struct }
}
pub fn gen_definition_unparser(m: &mut ModuleContext, n: &str, d: &Definition) {
m.define_function(
|mut ctxt| {
let mut body = Vec::new();
match d {
Definition::Or { pattern_0, pattern_1, pattern_n } => {
let mut ps = vec![&**pattern_0, &**pattern_1];
ps.extend(pattern_n);
body.push(item(seq!["match value ", block(ps.iter().map(
| NamedAlternative { variant_label: name, pattern: pat } | ctxt.branch(|ctxt| {
let ctorname = item(name![names::render_constructor(n), names::render_constructor(name)]);
let (patpat, vc) = destruct(ctxt, ctorname, false, &pattern_type(pat));
item(seq![patpat, " => ", pattern_unparser(ctxt, pat, &vc), ","])
})).collect())]));
}
Definition::And { pattern_0, pattern_1, pattern_n } => {
let mut ps = vec![&**pattern_0, &**pattern_1];
ps.extend(pattern_n);
let (patpat, vc) = destruct(&mut ctxt, item(names::render_constructor(n)), true, &record_type(&ps));
push_let(&mut body, item(patpat), item("value"));
body.push(item(seq!["preserves::value::merge(vec!", brackets(ps.iter().map(
|p| named_pattern_unparser(&mut ctxt, p, &vc)).collect()), ")"]));
}
Definition::Pattern(p) => {
let (patpat, vc) = destruct(&mut ctxt, item(names::render_constructor(n)), true, &pattern_type(p));
push_let(&mut body, item(patpat), item("value"));
body.push(pattern_unparser(&mut ctxt, p, &vc));
}
}
item(seq!["impl std::convert::From", anglebrackets![seq!["&", names::render_constructor(n)]],
" for preserves::value::IOValue ", block![
seq!["fn from(value: &", names::render_constructor(n), ") -> Self ",
block(body)]]])
});
}
fn destruct(
ctxt: &mut FunctionContext,
ctorname: Item,
is_struct: bool,
ty: &TSimple,
) -> (impl Emittable, ValueContext) {
match ty {
TSimple::Field(TField::Unit) => (seq![ctorname], normal_none(is_struct)),
TSimple::Field(_) => {
let src = ctxt.gentempname();
(seq![ctorname, parens![src.to_owned()]], normal_src(src, is_struct))
}
TSimple::Record(TRecord(fs)) => {
for (fname, fty) in fs {
let fsrc = ctxt.gentempname();
ctxt.capture(names::render_fieldname(fname), fty.clone(), fsrc);
}
(seq![
ctorname, " ", braces(ctxt.captures.iter().map(
|c| item(seq![c.field_name.clone(), ": ", c.source_expr.clone()])).collect())],
normal_none(is_struct))
}
}
}
fn simple_pattern_unparser(
ctxt: &mut FunctionContext,
p: &SimplePattern,
vc: &ValueContext,
) -> Item {
let src = &vc.src;
match p {
SimplePattern::Any =>
item(seq![src.as_ref().unwrap().to_owned(), ".clone()"]),
SimplePattern::Atom { atom_kind: k } => {
if let AtomKind::Symbol = &**k {
item(seq!["preserves::value::Value::symbol(", src.as_ref().unwrap().to_owned(), ").wrap()"])
} else {
item(seq!["preserves::value::Value::from(", src.as_ref().unwrap().to_owned(), ").wrap()"])
}
}
SimplePattern::Embedded { .. } =>
item(seq!["preserves::value::Value::Domain(", src.as_ref().unwrap().to_owned(), ").wrap()"]),
SimplePattern::Lit { value } =>
item(seq![parens![ctxt.m.define_literal(value)], ".clone()"]),
SimplePattern::Seqof { pattern } => {
let mut fields_sink = sequenceify(ctxt, vc);
let tmp = ctxt.gentempname();
fields_sink.body.push(item(seq![
"for ", tmp.to_owned(), " in ",
src.as_ref().unwrap().to_owned(), " ", block![
seq![fields_sink.vec_expr.clone(), ".push(",
simple_pattern_unparser(ctxt,
pattern,
&normal_src(tmp, true)), ");"]]]));
finish(fields_sink)
}
SimplePattern::Setof { pattern } => {
let tmp = ctxt.gentempname();
item(seq!["preserves::value::Value::Set(",
src.as_ref().unwrap().to_owned(), ".iter().map(|", tmp.to_owned(), "| ",
simple_pattern_unparser(ctxt, pattern, &normal_src(tmp, true)),
").collect()).wrap()"])
}
SimplePattern::Dictof { key, value } => {
let tmp_key = ctxt.gentempname();
let tmp_value = ctxt.gentempname();
item(seq!["preserves::value::Value::Dictionary(",
src.as_ref().unwrap().to_owned(),
".iter().map(|(", tmp_key.to_owned(), ", ", tmp_value.to_owned(), ")| ",
parens![simple_pattern_unparser(ctxt, key, &normal_src(tmp_key, true)),
simple_pattern_unparser(ctxt, value, &normal_src(tmp_value, true))],
").collect()).wrap()"])
}
SimplePattern::Ref(_r) =>
item(seq!["preserves::value::IOValue::from(", src.as_ref().unwrap().to_owned(),
if vc.is_struct { "" } else { ".as_ref()" },
")"]),
}
}
fn named_pattern_unparser(
ctxt: &mut FunctionContext,
p: &NamedPattern,
vc: &ValueContext,
) -> Item {
match p {
NamedPattern::Anonymous(p) =>
pattern_unparser(ctxt, p, vc),
NamedPattern::Named(b) => {
let Binding { name, pattern} = &**b;
let src = ctxt.lookup_capture(&names::render_fieldname(name)).source_expr.to_owned();
simple_pattern_unparser(ctxt, pattern, &ValueContext {
src: Some(src),
sink: vc.sink.clone(),
is_struct: vc.is_struct,
})
}
}
}
fn pattern_unparser(
ctxt: &mut FunctionContext,
p: &Pattern,
vc: &ValueContext,
) -> Item {
match p {
Pattern::SimplePattern(s) =>
simple_pattern_unparser(ctxt, s, vc),
Pattern::CompoundPattern(c) => {
match &**c {
CompoundPattern::Rec { label, fields } => {
let rtmp = ctxt.gentempname();
let mut body = Vec::new();
push_let_mut(&mut body,
item(rtmp.to_owned()),
item(seq!["preserves::value::Record(vec![",
named_pattern_unparser(ctxt, label, &normal_none(vc.is_struct)),
"])"]));
named_pattern_unparser(ctxt, fields, &ValueContext {
src: None,
sink: ValueSink::Fields(Rc::new(Cell::new(Some(FieldsSink {
finish: item(seq![rtmp.clone(), ".finish().wrap()"]),
vec_expr: item(seq![rtmp.clone(), ".fields_vec_mut()"]),
body: body,
})))),
is_struct: vc.is_struct,
})
},
CompoundPattern::Tuple { patterns } => {
let mut fields_sink = sequenceify(ctxt, vc);
fixed_sequence_parser(ctxt, patterns, &mut fields_sink, vc.is_struct);
finish(fields_sink)
},
CompoundPattern::TuplePrefix { fixed, variable } => {
let mut fields_sink = sequenceify(ctxt, vc);
fixed_sequence_parser(ctxt, fixed, &mut fields_sink, vc.is_struct);
named_pattern_unparser(ctxt, &promote(variable), &ValueContext {
src: vc.src.clone(),
sink: ValueSink::Fields(Rc::new(Cell::new(Some(fields_sink)))),
is_struct: true,
})
},
CompoundPattern::Dict { entries } => {
let dtmp = item(ctxt.gentempname());
let mut body = Vec::new();
push_let_mut(&mut body, dtmp.clone(), item("preserves::value::Map::new()"));
for (key_lit, value_pat) in entries.0.iter() {
body.push(item(seq![dtmp.clone(), ".insert", parens![
seq![parens![ctxt.m.define_literal(key_lit)], ".clone()"],
named_pattern_unparser(ctxt, &promote(value_pat), &normal_none(vc.is_struct))], ";"]));
}
body.push(item(seq!["preserves::value::Value::Dictionary(", dtmp, ").wrap()"]));
item(block(body))
}
}
},
}
}
fn sequenceify<'a>(
ctxt: &mut FunctionContext,
vc: &'a ValueContext,
) -> FieldsSink {
match vc {
ValueContext { sink: ValueSink::Fields(fields_sink), .. } =>
(**fields_sink).take().unwrap(),
_ => {
let rtmp = item(ctxt.gentempname());
let mut body = Vec::new();
push_let_mut(&mut body, rtmp.clone(), item("vec![]"));
FieldsSink {
finish: item(seq![
"preserves::value::Value::Sequence", parens![rtmp.clone()], ".wrap()"]),
vec_expr: rtmp,
body: body,
}
}
}
}
fn finish(mut fields_sink: FieldsSink) -> Item {
fields_sink.body.push(fields_sink.finish);
item(block(fields_sink.body))
}
fn fixed_sequence_parser(
ctxt: &mut FunctionContext,
patterns: &Vec<NamedPattern>,
fields_sink: &mut FieldsSink,
is_struct: bool,
) {
for p in patterns {
fields_sink.body.push(item(seq![fields_sink.vec_expr.clone(), ".push", parens![
named_pattern_unparser(ctxt, p, &normal_none(is_struct))], ";"]));
}
}

View File

@ -30,14 +30,15 @@ mod tests {
#[test]
fn metaschema_parsing() -> Result<(), std::io::Error> {
use preserves::value::Reader;
use preserves::value::{IOValue, Reader};
use std::convert::TryFrom;
use std::convert::From;
let mut f = std::fs::File::open("../../../schema/schema.bin")?;
let mut reader = preserves::value::PackedReader::decode_read(&mut f);
let schema = reader.demand_next(false)?;
println!("{:#?}", crate::metaschema::Schema::try_from(&schema));
let parsed = crate::metaschema::Schema::try_from(&schema).expect("successful parse");
assert_eq!(schema, IOValue::from(&parsed));
Ok(())
}
}

View File

@ -162,6 +162,20 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for AtomKind {
}
}
impl std::convert::From<&AtomKind> for preserves::value::IOValue {
fn from(value: &AtomKind) -> Self {
match value {
AtomKind::Boolean => (&*LIT0).clone(),
AtomKind::Float => (&*LIT1).clone(),
AtomKind::Double => (&*LIT2).clone(),
AtomKind::SignedInteger => (&*LIT3).clone(),
AtomKind::String => (&*LIT4).clone(),
AtomKind::ByteString => (&*LIT5).clone(),
AtomKind::Symbol => (&*LIT6).clone(),
}
}
}
impl std::convert::TryFrom<&preserves::value::IOValue> for Binding {
type Error = ();
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
@ -175,6 +189,18 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Binding {
}
}
impl std::convert::From<&Binding> for preserves::value::IOValue {
fn from(value: &Binding) -> Self {
let Binding {name: _tmp0, pattern: _tmp1} = value;
{
let mut _tmp2 = preserves::value::Record(vec![(&*LIT7).clone()]);
_tmp2.fields_vec_mut().push(preserves::value::Value::symbol(_tmp0).wrap());
_tmp2.fields_vec_mut().push(preserves::value::IOValue::from(_tmp1));
_tmp2.finish().wrap()
}
}
}
impl std::convert::TryFrom<&preserves::value::IOValue> for Bundle {
type Error = ();
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
@ -187,6 +213,17 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Bundle {
}
}
impl std::convert::From<&Bundle> for preserves::value::IOValue {
fn from(value: &Bundle) -> Self {
let Bundle {modules: _tmp0} = value;
{
let mut _tmp1 = preserves::value::Record(vec![(&*LIT8).clone()]);
_tmp1.fields_vec_mut().push(preserves::value::IOValue::from(_tmp0));
_tmp1.finish().wrap()
}
}
}
fn _parse_compound_pattern_rec(value: &preserves::value::IOValue) -> std::result::Result<CompoundPattern, ()> {
let _tmp0 = value.value().to_record(None).map_err(|_| ())?;
if _tmp0.label() != &*LIT9 { return Err(()); }
@ -240,6 +277,47 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for CompoundPattern {
}
}
impl std::convert::From<&CompoundPattern> for preserves::value::IOValue {
fn from(value: &CompoundPattern) -> Self {
match value {
CompoundPattern::Rec {label: _tmp0, fields: _tmp1} => {
let mut _tmp2 = preserves::value::Record(vec![(&*LIT9).clone()]);
_tmp2.fields_vec_mut().push(preserves::value::IOValue::from(_tmp0.as_ref()));
_tmp2.fields_vec_mut().push(preserves::value::IOValue::from(_tmp1.as_ref()));
_tmp2.finish().wrap()
},
CompoundPattern::Tuple {patterns: _tmp0} => {
let mut _tmp1 = preserves::value::Record(vec![(&*LIT10).clone()]);
_tmp1.fields_vec_mut().push(
{
let mut _tmp2 = vec![];
for _tmp3 in _tmp0 {_tmp2.push(preserves::value::IOValue::from(_tmp3));}
preserves::value::Value::Sequence(_tmp2).wrap()
}
);
_tmp1.finish().wrap()
},
CompoundPattern::TuplePrefix {fixed: _tmp0, variable: _tmp1} => {
let mut _tmp2 = preserves::value::Record(vec![(&*LIT11).clone()]);
_tmp2.fields_vec_mut().push(
{
let mut _tmp3 = vec![];
for _tmp4 in _tmp0 {_tmp3.push(preserves::value::IOValue::from(_tmp4));}
preserves::value::Value::Sequence(_tmp3).wrap()
}
);
_tmp2.fields_vec_mut().push(preserves::value::IOValue::from(_tmp1.as_ref()));
_tmp2.finish().wrap()
},
CompoundPattern::Dict {entries: _tmp0} => {
let mut _tmp1 = preserves::value::Record(vec![(&*LIT12).clone()]);
_tmp1.fields_vec_mut().push(preserves::value::IOValue::from(_tmp0.as_ref()));
_tmp1.finish().wrap()
},
}
}
}
fn _parse_definition_or(value: &preserves::value::IOValue) -> std::result::Result<Definition, ()> {
let _tmp0 = value.value().to_record(None).map_err(|_| ())?;
if _tmp0.label() != &*LIT13 { return Err(()); }
@ -291,6 +369,40 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Definition {
}
}
impl std::convert::From<&Definition> for preserves::value::IOValue {
fn from(value: &Definition) -> Self {
match value {
Definition::Or {pattern_0: _tmp0, pattern_1: _tmp1, pattern_n: _tmp2} => {
let mut _tmp3 = preserves::value::Record(vec![(&*LIT13).clone()]);
_tmp3.fields_vec_mut().push(
{
let mut _tmp4 = vec![];
_tmp4.push(preserves::value::IOValue::from(_tmp0.as_ref()));
_tmp4.push(preserves::value::IOValue::from(_tmp1.as_ref()));
for _tmp5 in _tmp2 {_tmp4.push(preserves::value::IOValue::from(_tmp5));}
preserves::value::Value::Sequence(_tmp4).wrap()
}
);
_tmp3.finish().wrap()
},
Definition::And {pattern_0: _tmp0, pattern_1: _tmp1, pattern_n: _tmp2} => {
let mut _tmp3 = preserves::value::Record(vec![(&*LIT14).clone()]);
_tmp3.fields_vec_mut().push(
{
let mut _tmp4 = vec![];
_tmp4.push(preserves::value::IOValue::from(_tmp0.as_ref()));
_tmp4.push(preserves::value::IOValue::from(_tmp1.as_ref()));
for _tmp5 in _tmp2 {_tmp4.push(preserves::value::IOValue::from(_tmp5));}
preserves::value::Value::Sequence(_tmp4).wrap()
}
);
_tmp3.finish().wrap()
},
Definition::Pattern(_tmp0) => preserves::value::IOValue::from(_tmp0.as_ref()),
}
}
}
impl std::convert::TryFrom<&preserves::value::IOValue> for Definitions {
type Error = ();
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
@ -304,6 +416,16 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Definitions {
}
}
impl std::convert::From<&Definitions> for preserves::value::IOValue {
fn from(value: &Definitions) -> Self {
let Definitions(_tmp0) = value;
preserves::value::Value::Dictionary(_tmp0.iter().map(|(_tmp1, _tmp2)| (
preserves::value::Value::symbol(_tmp1).wrap(),
preserves::value::IOValue::from(_tmp2)
)).collect()).wrap()
}
}
impl std::convert::TryFrom<&preserves::value::IOValue> for DictionaryEntries {
type Error = ();
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
@ -317,6 +439,13 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for DictionaryEntries {
}
}
impl std::convert::From<&DictionaryEntries> for preserves::value::IOValue {
fn from(value: &DictionaryEntries) -> Self {
let DictionaryEntries(_tmp0) = value;
preserves::value::Value::Dictionary(_tmp0.iter().map(|(_tmp1, _tmp2)| (_tmp1.clone(), preserves::value::IOValue::from(_tmp2))).collect()).wrap()
}
}
fn _parse_embedded_type_name_ref(value: &preserves::value::IOValue) -> std::result::Result<EmbeddedTypeName, ()> {
let _tmp0 = Ref::try_from(value)?;
Ok(EmbeddedTypeName::Ref(std::boxed::Box::new(_tmp0)))
@ -337,6 +466,15 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for EmbeddedTypeName {
}
}
impl std::convert::From<&EmbeddedTypeName> for preserves::value::IOValue {
fn from(value: &EmbeddedTypeName) -> Self {
match value {
EmbeddedTypeName::Ref(_tmp0) => preserves::value::IOValue::from(_tmp0.as_ref()),
EmbeddedTypeName::False => (&*LIT15).clone(),
}
}
}
impl std::convert::TryFrom<&preserves::value::IOValue> for ModulePath {
type Error = ();
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
@ -350,6 +488,17 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for ModulePath {
}
}
impl std::convert::From<&ModulePath> for preserves::value::IOValue {
fn from(value: &ModulePath) -> Self {
let ModulePath(_tmp0) = value;
{
let mut _tmp1 = vec![];
for _tmp2 in _tmp0 {_tmp1.push(preserves::value::Value::symbol(_tmp2).wrap());}
preserves::value::Value::Sequence(_tmp1).wrap()
}
}
}
impl std::convert::TryFrom<&preserves::value::IOValue> for Modules {
type Error = ();
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
@ -363,6 +512,13 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Modules {
}
}
impl std::convert::From<&Modules> for preserves::value::IOValue {
fn from(value: &Modules) -> Self {
let Modules(_tmp0) = value;
preserves::value::Value::Dictionary(_tmp0.iter().map(|(_tmp1, _tmp2)| (preserves::value::IOValue::from(_tmp1), preserves::value::IOValue::from(_tmp2))).collect()).wrap()
}
}
impl std::convert::TryFrom<&preserves::value::IOValue> for NamedAlternative {
type Error = ();
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
@ -374,6 +530,18 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for NamedAlternative {
}
}
impl std::convert::From<&NamedAlternative> for preserves::value::IOValue {
fn from(value: &NamedAlternative) -> Self {
let NamedAlternative {variant_label: _tmp0, pattern: _tmp1} = value;
{
let mut _tmp2 = vec![];
_tmp2.push(preserves::value::Value::from(_tmp0).wrap());
_tmp2.push(preserves::value::IOValue::from(_tmp1));
preserves::value::Value::Sequence(_tmp2).wrap()
}
}
}
fn _parse_named_pattern_named(value: &preserves::value::IOValue) -> std::result::Result<NamedPattern, ()> {
let _tmp0 = Binding::try_from(value)?;
Ok(NamedPattern::Named(std::boxed::Box::new(_tmp0)))
@ -393,6 +561,15 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for NamedPattern {
}
}
impl std::convert::From<&NamedPattern> for preserves::value::IOValue {
fn from(value: &NamedPattern) -> Self {
match value {
NamedPattern::Named(_tmp0) => preserves::value::IOValue::from(_tmp0.as_ref()),
NamedPattern::Anonymous(_tmp0) => preserves::value::IOValue::from(_tmp0.as_ref()),
}
}
}
fn _parse_named_simple_pattern_named(value: &preserves::value::IOValue) -> std::result::Result<NamedSimplePattern, ()> {
let _tmp0 = Binding::try_from(value)?;
Ok(NamedSimplePattern::Named(std::boxed::Box::new(_tmp0)))
@ -412,6 +589,15 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for NamedSimplePattern {
}
}
impl std::convert::From<&NamedSimplePattern> for preserves::value::IOValue {
fn from(value: &NamedSimplePattern) -> Self {
match value {
NamedSimplePattern::Named(_tmp0) => preserves::value::IOValue::from(_tmp0.as_ref()),
NamedSimplePattern::Anonymous(_tmp0) => preserves::value::IOValue::from(_tmp0.as_ref()),
}
}
}
fn _parse_pattern_simple_pattern(value: &preserves::value::IOValue) -> std::result::Result<Pattern, ()> {
let _tmp0 = SimplePattern::try_from(value)?;
Ok(Pattern::SimplePattern(std::boxed::Box::new(_tmp0)))
@ -431,6 +617,15 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Pattern {
}
}
impl std::convert::From<&Pattern> for preserves::value::IOValue {
fn from(value: &Pattern) -> Self {
match value {
Pattern::SimplePattern(_tmp0) => preserves::value::IOValue::from(_tmp0.as_ref()),
Pattern::CompoundPattern(_tmp0) => preserves::value::IOValue::from(_tmp0.as_ref()),
}
}
}
impl std::convert::TryFrom<&preserves::value::IOValue> for Ref {
type Error = ();
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
@ -444,6 +639,18 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Ref {
}
}
impl std::convert::From<&Ref> for preserves::value::IOValue {
fn from(value: &Ref) -> Self {
let Ref {module: _tmp0, name: _tmp1} = value;
{
let mut _tmp2 = preserves::value::Record(vec![(&*LIT16).clone()]);
_tmp2.fields_vec_mut().push(preserves::value::IOValue::from(_tmp0));
_tmp2.fields_vec_mut().push(preserves::value::Value::symbol(_tmp1).wrap());
_tmp2.finish().wrap()
}
}
}
impl std::convert::TryFrom<&preserves::value::IOValue> for Schema {
type Error = ();
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
@ -462,6 +669,25 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Schema {
}
}
impl std::convert::From<&Schema> for preserves::value::IOValue {
fn from(value: &Schema) -> Self {
let Schema {definitions: _tmp0, embedded_type: _tmp1, version: _tmp2} = value;
{
let mut _tmp3 = preserves::value::Record(vec![(&*LIT17).clone()]);
_tmp3.fields_vec_mut().push(
{
let mut _tmp4 = preserves::value::Map::new();
_tmp4.insert((&*LIT18).clone(), preserves::value::IOValue::from(_tmp0));
_tmp4.insert((&*LIT19).clone(), preserves::value::IOValue::from(_tmp1));
_tmp4.insert((&*LIT20).clone(), preserves::value::IOValue::from(_tmp2));
preserves::value::Value::Dictionary(_tmp4).wrap()
}
);
_tmp3.finish().wrap()
}
}
}
fn _parse_simple_pattern_any(value: &preserves::value::IOValue) -> std::result::Result<SimplePattern, ()> {if value != &*LIT21 { return Err(()); } let _tmp0 = (); Ok(SimplePattern::Any)}
fn _parse_simple_pattern_atom(value: &preserves::value::IOValue) -> std::result::Result<SimplePattern, ()> {
@ -539,8 +765,50 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for SimplePattern {
}
}
impl std::convert::From<&SimplePattern> for preserves::value::IOValue {
fn from(value: &SimplePattern) -> Self {
match value {
SimplePattern::Any => (&*LIT21).clone(),
SimplePattern::Atom {atom_kind: _tmp0} => {
let mut _tmp1 = preserves::value::Record(vec![(&*LIT22).clone()]);
_tmp1.fields_vec_mut().push(preserves::value::IOValue::from(_tmp0.as_ref()));
_tmp1.finish().wrap()
},
SimplePattern::Embedded {interface: _tmp0} => {
let mut _tmp1 = preserves::value::Record(vec![(&*LIT23).clone()]);
_tmp1.fields_vec_mut().push(preserves::value::IOValue::from(_tmp0.as_ref()));
_tmp1.finish().wrap()
},
SimplePattern::Lit {value: _tmp0} => {
let mut _tmp1 = preserves::value::Record(vec![(&*LIT24).clone()]);
_tmp1.fields_vec_mut().push(_tmp0.clone());
_tmp1.finish().wrap()
},
SimplePattern::Seqof {pattern: _tmp0} => {
let mut _tmp1 = preserves::value::Record(vec![(&*LIT25).clone()]);
_tmp1.fields_vec_mut().push(preserves::value::IOValue::from(_tmp0.as_ref()));
_tmp1.finish().wrap()
},
SimplePattern::Setof {pattern: _tmp0} => {
let mut _tmp1 = preserves::value::Record(vec![(&*LIT26).clone()]);
_tmp1.fields_vec_mut().push(preserves::value::IOValue::from(_tmp0.as_ref()));
_tmp1.finish().wrap()
},
SimplePattern::Dictof {key: _tmp0, value: _tmp1} => {
let mut _tmp2 = preserves::value::Record(vec![(&*LIT27).clone()]);
_tmp2.fields_vec_mut().push(preserves::value::IOValue::from(_tmp0.as_ref()));
_tmp2.fields_vec_mut().push(preserves::value::IOValue::from(_tmp1.as_ref()));
_tmp2.finish().wrap()
},
SimplePattern::Ref(_tmp0) => preserves::value::IOValue::from(_tmp0.as_ref()),
}
}
}
impl std::convert::TryFrom<&preserves::value::IOValue> for Version {
type Error = ();
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {if value != &*LIT28 { return Err(()); } let _tmp0 = (); Ok(Version)}
}
impl std::convert::From<&Version> for preserves::value::IOValue {fn from(value: &Version) -> Self {let Version = value; (&*LIT28).clone()}}

View File

@ -2,6 +2,7 @@ use num::bigint::BigInt;
use num::traits::cast::ToPrimitive;
use std::borrow::Cow;
use std::cmp::Ordering;
use std::convert::From;
use std::convert::TryFrom;
use std::convert::TryInto;
use std::fmt::Debug;
@ -217,9 +218,11 @@ impl<N: NestedValue<D>, D: Domain> From<i64> for Value<N, D> { fn from(v: i64) -
impl<N: NestedValue<D>, D: Domain> From<u128> for Value<N, D> { fn from(v: u128) -> Self { Value::SignedInteger(SignedInteger::from(v)) } }
impl<N: NestedValue<D>, D: Domain> From<i128> for Value<N, D> { fn from(v: i128) -> Self { Value::SignedInteger(SignedInteger::from(v)) } }
impl<N: NestedValue<D>, D: Domain> From<&BigInt> for Value<N, D> { fn from(v: &BigInt) -> Self { Value::SignedInteger(SignedInteger::from(Cow::Borrowed(v))) } }
impl<N: NestedValue<D>, D: Domain> From<&SignedInteger> for Value<N, D> { fn from(v: &SignedInteger) -> Self { Value::SignedInteger(v.clone()) } }
impl<N: NestedValue<D>, D: Domain> From<&str> for Value<N, D> { fn from(v: &str) -> Self { Value::String(String::from(v)) } }
impl<N: NestedValue<D>, D: Domain> From<String> for Value<N, D> { fn from(v: String) -> Self { Value::String(v) } }
impl<N: NestedValue<D>, D: Domain> From<&String> for Value<N, D> { fn from(v: &String) -> Self { Value::String(v.to_owned()) } }
impl<N: NestedValue<D>, D: Domain> From<&[u8]> for Value<N, D> { fn from(v: &[u8]) -> Self { Value::ByteString(Vec::from(v)) } }
// impl<N: NestedValue<D>, D: Domain> From<Vec<u8>> for Value<N, D> { fn from(v: Vec<u8>) -> Self { Value::ByteString(v) } }