Initial commit (several days' worth)
This commit is contained in:
parent
60d1be41a3
commit
4144a90b9d
|
@ -1,4 +1,5 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"preserves",
|
||||
"preserves-schema",
|
||||
]
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "preserves-schema"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
preserves = { path = "../preserves" }
|
||||
|
||||
structopt = "0.3.14"
|
||||
glob = "0.3.0"
|
||||
|
||||
convert_case = "0.4.0"
|
||||
|
||||
lazy_static = "1.4.0"
|
|
@ -0,0 +1,6 @@
|
|||
all:
|
||||
@echo please use cargo
|
||||
|
||||
regenerate:
|
||||
cargo run -- -o $(CURDIR)/src --prefix schema ../../../schema/schema.bin > src/metaschema.rs.tmp
|
||||
mv src/metaschema.rs.tmp src/metaschema.rs
|
|
@ -0,0 +1,66 @@
|
|||
use std::path::PathBuf;
|
||||
use std::fs::File;
|
||||
use preserves::value::packed::PackedReader;
|
||||
use preserves::value::{NestedValue, Reader};
|
||||
use structopt::StructOpt;
|
||||
use glob::glob;
|
||||
|
||||
use preserves_schema::compiler::{CompilerConfig, compile};
|
||||
|
||||
#[derive(Clone, StructOpt, Debug)]
|
||||
struct CommandLine {
|
||||
#[structopt(short, long)]
|
||||
output_dir: PathBuf,
|
||||
|
||||
#[structopt(long)]
|
||||
prefix: Option<String>,
|
||||
|
||||
input_glob: Vec<String>,
|
||||
}
|
||||
|
||||
fn inputs(globs: &Vec<String>) -> Vec<PathBuf> {
|
||||
let mut result = Vec::new();
|
||||
for g in globs.iter() {
|
||||
match glob(g) {
|
||||
Ok(paths) =>
|
||||
for p in paths {
|
||||
match p {
|
||||
Ok(s) => result.push(s),
|
||||
Err(e) => println!("warning: {:?}", e),
|
||||
}
|
||||
}
|
||||
Err(e) => println!("warning: {:?}", e),
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
let args = CommandLine::from_args();
|
||||
|
||||
let prefix = match &args.prefix {
|
||||
Some(s) => s.split(".").map(str::to_string).collect(),
|
||||
None => vec![],
|
||||
};
|
||||
|
||||
let mut config = CompilerConfig::new(args.output_dir);
|
||||
|
||||
for i in inputs(&args.input_glob) {
|
||||
let mut f = File::open(&i)?;
|
||||
let mut reader = PackedReader::decode_read(&mut f);
|
||||
let schema = reader.demand_next(false)?;
|
||||
if let Some(s) = schema.value().as_simple_record("schema", Some(1)) {
|
||||
config.bundle.insert(prefix.clone(), s[0].clone());
|
||||
} else if let Some(b) = schema.value().as_simple_record("bundle", Some(1)) {
|
||||
for (k, v) in b[0].value().to_dictionary()? {
|
||||
let mut name = prefix.clone();
|
||||
for p in k.value().to_sequence()? {
|
||||
name.push(p.value().to_string()?.to_owned());
|
||||
}
|
||||
config.bundle.insert(name, v.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compile(&config)
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
use preserves::value::{Map, IOValue};
|
||||
|
||||
use crate::syntax::block::Item;
|
||||
|
||||
use super::types;
|
||||
|
||||
pub struct ModuleContext {
|
||||
pub literals: Map<IOValue, String>,
|
||||
pub typedefs: Vec<Item>,
|
||||
pub functiondefs: Vec<Item>,
|
||||
}
|
||||
|
||||
pub struct FunctionContext<'a> {
|
||||
pub m: &'a mut ModuleContext,
|
||||
pub temp_counter: usize,
|
||||
pub temps: Map<types::TDefinition, Vec<String>>,
|
||||
pub captures: Vec<Capture>,
|
||||
}
|
||||
|
||||
pub struct Capture {
|
||||
pub field_name: String,
|
||||
pub source_expr: String,
|
||||
}
|
||||
|
||||
impl ModuleContext {
|
||||
pub fn new() -> Self {
|
||||
ModuleContext {
|
||||
literals: Map::new(),
|
||||
typedefs: Vec::new(),
|
||||
functiondefs: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn define_literal(&mut self, v: &IOValue) -> String {
|
||||
let next_id = format!("LIT{}", self.literals.len());
|
||||
"&*".to_owned() + self.literals.entry(v.clone()).or_insert(next_id)
|
||||
}
|
||||
|
||||
pub fn define_type(&mut self, i: Item) {
|
||||
self.typedefs.push(i)
|
||||
}
|
||||
|
||||
pub fn define_function<F: FnOnce(FunctionContext) -> Item>(&mut self, f: F) {
|
||||
let i = f(FunctionContext::new(self));
|
||||
self.functiondefs.push(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FunctionContext<'a> {
|
||||
pub fn new(m: &'a mut ModuleContext) -> Self {
|
||||
FunctionContext {
|
||||
m: m,
|
||||
temp_counter: 0,
|
||||
temps: Map::new(),
|
||||
captures: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn capture(&mut self, field_name: &str, source_expr: &str) {
|
||||
self.captures.push(Capture {
|
||||
field_name: field_name.to_owned(),
|
||||
source_expr: source_expr.to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn gentempname(&mut self) -> String {
|
||||
let i = self.temp_counter;
|
||||
self.temp_counter += 1;
|
||||
format!("_tmp{}", i)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
pub mod types;
|
||||
pub mod names;
|
||||
pub mod context;
|
||||
pub mod parsers;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use preserves::value::{Map, IOValue, NestedValue, Value};
|
||||
|
||||
use crate::syntax::block::constructors::*;
|
||||
|
||||
pub type ModulePath = Vec<String>;
|
||||
|
||||
pub type Schema = IOValue;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CompilerConfig {
|
||||
pub bundle: Map<ModulePath, Schema>,
|
||||
pub output_dir: PathBuf,
|
||||
}
|
||||
|
||||
impl CompilerConfig {
|
||||
pub fn new(output_dir: PathBuf) -> Self {
|
||||
CompilerConfig {
|
||||
bundle: Map::new(),
|
||||
output_dir: output_dir,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
|
||||
for (k, v) in config.bundle.iter() {
|
||||
let mut output_path = config.output_dir.clone();
|
||||
output_path.extend(k);
|
||||
output_path.set_extension("rs");
|
||||
let mut m = context::ModuleContext::new();
|
||||
|
||||
// println!("\n{:?}", &output_path);
|
||||
|
||||
// TODO: embedded type
|
||||
|
||||
let definitions = v.value().to_dictionary()?.get(&Value::symbol("definitions").wrap())
|
||||
.unwrap().value().to_dictionary()?;
|
||||
|
||||
for (n, d) in definitions.iter() {
|
||||
m.define_type(item(types::render_definition_type(
|
||||
n.value().to_symbol()?,
|
||||
&types::definition_type(d)?)));
|
||||
|
||||
parsers::gen_definition_parser(&mut m, n.value().to_symbol()?, &d);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
println!("#![allow(unused_parens)]");
|
||||
println!();
|
||||
println!("use std::convert::TryFrom;");
|
||||
println!("use preserves::value::{{NestedValue, Reader}};");
|
||||
println!("use lazy_static::lazy_static;");
|
||||
println!();
|
||||
|
||||
println!("lazy_static! {{");
|
||||
for (value, name) in m.literals {
|
||||
let bs = preserves::value::PackedWriter::encode(&value).unwrap();
|
||||
println!(" pub static ref {}: preserves::value::IOValue = /* {:?} */ preserves::value::PackedReader::decode_bytes(&vec!{:?}).demand_next(false).unwrap();",
|
||||
name,
|
||||
value,
|
||||
bs);
|
||||
}
|
||||
println!("}}\n");
|
||||
|
||||
for i in m.typedefs { println!("{:?}\n", i); }
|
||||
for i in m.functiondefs { println!("{:?}\n", i); }
|
||||
}
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
use crate::syntax::block::Emittable;
|
||||
use crate::syntax::block::constructors::*;
|
||||
use convert_case::{Case, Casing};
|
||||
|
||||
pub fn render_ref(pieces: Vec<String>) -> impl Emittable {
|
||||
let mut items = Vec::new();
|
||||
for p in pieces { items.push(item(p)); }
|
||||
name(items)
|
||||
}
|
||||
|
||||
pub fn render_constructor(n: &str) -> String {
|
||||
n.to_case(Case::UpperCamel)
|
||||
}
|
||||
|
||||
pub fn render_fieldname(n: &str) -> String {
|
||||
n.to_case(Case::Snake)
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
use crate::*;
|
||||
use crate::syntax::block::Item;
|
||||
use crate::syntax::block::constructors::*;
|
||||
use preserves::value::{IOValue, NestedValue};
|
||||
use super::names;
|
||||
use super::types::*;
|
||||
use super::context::{ModuleContext, FunctionContext};
|
||||
|
||||
pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &IOValue) {
|
||||
m.define_function(
|
||||
|mut ctxt| {
|
||||
let mut body = Vec::new();
|
||||
|
||||
if let Some(fs) = d.value().as_simple_record("or", Some(1)) {
|
||||
for e in fs[0].value().to_sequence().unwrap() {
|
||||
let e = e.value().to_sequence().unwrap();
|
||||
let name = e[0].value().to_string().unwrap();
|
||||
let pat = &e[1];
|
||||
let fname = seq!["_parse_", names::render_fieldname(n), "_", names::render_fieldname(name)];
|
||||
let ctorname = item(name![names::render_constructor(n), names::render_constructor(name)]);
|
||||
ctxt.m.define_function(
|
||||
|mut ctxt| {
|
||||
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, &TDefinition::Simple(simple_type(pat).unwrap()), dest, &mut body);
|
||||
item(seq!["fn ", fname.clone(), "(value: &preserves::value::IOValue) -> ",
|
||||
"std::result::Result<", names::render_constructor(n), ", ()> ",
|
||||
block(body)])
|
||||
});
|
||||
body.push(item(seq!["if let Ok(r) = ", fname, "(value) { return Ok(r); }"]));
|
||||
}
|
||||
body.push(item(seq!["Err(())"]));
|
||||
} else if let Some(fs) = d.value().as_simple_record("and", Some(1)) {
|
||||
for e in fs[0].value().to_sequence().unwrap() {
|
||||
pattern_parser(&mut ctxt, e, "value", None, &mut body);
|
||||
}
|
||||
construct(&ctxt, item(names::render_constructor(n)), &definition_type(d).unwrap(), None, &mut body);
|
||||
} else {
|
||||
let dest = pattern_parser(&mut ctxt, d, "value", None, &mut body);
|
||||
let dest = dest.as_ref().map(String::as_str);
|
||||
construct(&ctxt, item(names::render_constructor(n)), &definition_type(d).unwrap(), dest, &mut body);
|
||||
}
|
||||
|
||||
item(seq!["impl std::convert::TryFrom", anglebrackets!["&preserves::value::IOValue"], " for ",
|
||||
names::render_constructor(n), " ", block![
|
||||
seq!["type Error = ();"],
|
||||
seq!["fn try_from(value: &preserves::value::IOValue) -> ",
|
||||
"std::result::Result<Self, Self::Error> ",
|
||||
block(body)]]])
|
||||
});
|
||||
}
|
||||
|
||||
fn construct(
|
||||
ctxt: &FunctionContext,
|
||||
ctorname: Item,
|
||||
ty: &TDefinition,
|
||||
dest: Option<&str>,
|
||||
body: &mut Vec<Item>,
|
||||
) {
|
||||
match ty {
|
||||
TDefinition::Simple(TSimple::Field(TField::Unit)) =>
|
||||
body.push(item(seq!["Ok(", ctorname, ")"])),
|
||||
TDefinition::Simple(TSimple::Field(fieldty)) =>
|
||||
body.push(item(seq!["Ok(", ctorname, parens![store_wrap(fieldty, dest.unwrap())], ")"])),
|
||||
_ =>
|
||||
body.push(item(seq!["Ok(", ctorname, " ", braces(
|
||||
ctxt.captures.iter().map(
|
||||
|c| item(seq![c.field_name.clone(), ": ", c.source_expr.clone()])).collect()),
|
||||
")"])),
|
||||
}
|
||||
}
|
||||
|
||||
fn store_wrap(ty: &TField, expr: &str) -> String {
|
||||
match ty {
|
||||
TField::Unit
|
||||
| TField::Array(_)
|
||||
| TField::Set(_)
|
||||
| TField::Map(_, _) => expr.to_owned(),
|
||||
TField::Ref(_) => format!("std::boxed::Box::new({})", expr),
|
||||
TField::Base(_) => format!("{}.clone()", expr),
|
||||
}
|
||||
}
|
||||
|
||||
fn item_store_wrap(ty: &TField, expr: &str) -> String {
|
||||
match ty {
|
||||
TField::Unit
|
||||
| TField::Array(_)
|
||||
| TField::Set(_)
|
||||
| TField::Map(_, _)
|
||||
| TField::Ref(_) => expr.to_owned(),
|
||||
TField::Base(_) => format!("{}.clone()", expr),
|
||||
}
|
||||
}
|
||||
|
||||
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: &IOValue,
|
||||
src: &str,
|
||||
sequence_base: Option<usize>,
|
||||
body: &mut Vec<Item>,
|
||||
) -> Option<String> {
|
||||
let dest = ctxt.gentempname();
|
||||
if p.value().as_symbol() == Some(&"any".to_owned()) {
|
||||
push_let(body, &dest, item(src.to_owned()));
|
||||
Some(dest)
|
||||
} else if let Some(fs) = p.value().as_simple_record("atom", Some(1)) {
|
||||
match fs[0].value().as_symbol().unwrap().as_str() {
|
||||
"Boolean" => push_let(body, &dest, item(seq![src.to_owned(), ".value().to_boolean().map_err(|_| ())?"])),
|
||||
"Float" => push_let(body, &dest, item(seq![src.to_owned(), ".value().to_float().map_err(|_| ())?"])),
|
||||
"Double" => push_let(body, &dest, item(seq![src.to_owned(), ".value().to_double().map_err(|_| ())?"])),
|
||||
"SignedInteger" => push_let(body, &dest, item(seq![src.to_owned(), ".value().to_signedinteger().map_err(|_| ())?"])),
|
||||
"String" => push_let(body, &dest, item(seq![src.to_owned(), ".value().to_string().map_err(|_| ())?"])),
|
||||
"ByteString" => push_let(body, &dest, item(seq![src.to_owned(), ".value().to_bytestring().map_err(|_| ())?"])),
|
||||
"Symbol" => push_let(body, &dest, item(seq![src.to_owned(), ".value().to_symbol().map_err(|_| ())?"])),
|
||||
_ => panic!("Unexpected AtomKind"),
|
||||
}
|
||||
Some(dest)
|
||||
} else if let Some(_) = p.value().as_simple_record("embedded", Some(1)) {
|
||||
push_let(body, &dest, item(seq![src.to_owned(), ".value().to_embedded().map_err(|_| ())?"]));
|
||||
Some(dest)
|
||||
} else if let Some(fs) = p.value().as_simple_record("lit", Some(1)) {
|
||||
body.push(item(seq!["if ", src.to_owned(), " != ", ctxt.m.define_literal(&fs[0]),
|
||||
" { return Err(()); }"]));
|
||||
push_let(body, &dest, item("()"));
|
||||
Some(dest)
|
||||
} else if let Some(fs) = p.value().as_simple_record("seqof", Some(1)) {
|
||||
let (src, n) = sequenceify(ctxt, src, sequence_base, body);
|
||||
let tmp = ctxt.gentempname();
|
||||
let mut inner = Vec::new();
|
||||
let item_dest = simple_pattern_parser(ctxt, &fs[0], &tmp, None, &mut inner);
|
||||
inner.push(item(seq![
|
||||
dest.to_owned(), ".push(",
|
||||
item_store_wrap(&field_type(&fs[0]).unwrap().unwrap(), &item_dest.unwrap()), ");"]));
|
||||
push_let_mut(body, &dest, item("std::vec::Vec::new()"));
|
||||
body.push(item(seq!["for ", tmp.to_owned(),
|
||||
" in &", src.to_owned(), brackets![seq![n.to_string() , ".."]],
|
||||
" ", block(inner)]));
|
||||
Some(dest)
|
||||
} else if let Some(fs) = p.value().as_simple_record("setof", Some(1)) {
|
||||
let tmp = ctxt.gentempname();
|
||||
let mut inner = Vec::new();
|
||||
let item_dest = simple_pattern_parser(ctxt, &fs[0], &tmp, None, &mut inner);
|
||||
inner.push(item(seq![
|
||||
dest.to_owned(), ".insert(",
|
||||
item_store_wrap(&field_type(&fs[0]).unwrap().unwrap(), &item_dest.unwrap()), ");"]));
|
||||
push_let_mut(body, &dest, item("preserves::value::Set::new()"));
|
||||
body.push(item(seq!["for ", tmp.to_owned(),
|
||||
" in ", src.to_owned(), ".value().to_set().map_err(|_| ())?",
|
||||
" ", block(inner)]));
|
||||
Some(dest)
|
||||
} else if let Some(fs) = p.value().as_simple_record("dictof", Some(2)) {
|
||||
let tmp_key = ctxt.gentempname();
|
||||
let tmp_value = ctxt.gentempname();
|
||||
let mut inner = Vec::new();
|
||||
let key_dest = simple_pattern_parser(ctxt, &fs[0], &tmp_key, None, &mut inner);
|
||||
let value_dest = simple_pattern_parser(ctxt, &fs[1], &tmp_value, None, &mut inner);
|
||||
inner.push(item(seq![
|
||||
dest.to_owned(), ".insert(",
|
||||
item_store_wrap(&field_type(&fs[0]).unwrap().unwrap(), &key_dest.unwrap()), ", ",
|
||||
item_store_wrap(&field_type(&fs[1]).unwrap().unwrap(), &value_dest.unwrap()), ");"]));
|
||||
push_let_mut(body, &dest, 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)]));
|
||||
Some(dest)
|
||||
} else if let Some(fs) = p.value().as_simple_record("ref", Some(2)) {
|
||||
let mut n: Vec<String> = fs[0].value().to_sequence().unwrap()
|
||||
.iter().map(|s| s.value().to_symbol().unwrap().to_owned()).collect();
|
||||
use convert_case::{Case, Casing};
|
||||
n.push(fs[1].value().to_symbol().unwrap().to_case(Case::UpperCamel));
|
||||
let tf = name![names::render_ref(n), "try_from"];
|
||||
push_let(body, &dest, item(seq![tf,
|
||||
parens![src.to_owned()],
|
||||
"?"]));
|
||||
Some(dest)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn sequenceify(
|
||||
ctxt: &mut FunctionContext,
|
||||
src: &str,
|
||||
sequence_base: Option<usize>,
|
||||
body: &mut Vec<Item>,
|
||||
) -> (String, usize) {
|
||||
match sequence_base {
|
||||
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(|_| ())?"]));
|
||||
(tmp, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fixed_sequence_parser(
|
||||
ctxt: &mut FunctionContext,
|
||||
base: usize,
|
||||
ps: &[IOValue],
|
||||
src: &str,
|
||||
body: &mut Vec<Item>,
|
||||
) {
|
||||
let mut i = base;
|
||||
body.push(item(seq!["if ", src.to_owned(), ".len() - ", base.to_string(), " < ",
|
||||
ps.len().to_string(), " { return Err(()); }"]));
|
||||
for p in ps {
|
||||
pattern_parser(ctxt, p, &format!("(&{}[{}])", src, i), None, body);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn pattern_parser(
|
||||
ctxt: &mut FunctionContext,
|
||||
p: &IOValue,
|
||||
src: &str,
|
||||
sequence_base: Option<usize>,
|
||||
body: &mut Vec<Item>,
|
||||
) -> Option<String> {
|
||||
match simple_pattern_parser(ctxt, p, src, sequence_base, body) {
|
||||
Some(dest) => Some(dest),
|
||||
None => {
|
||||
// Compound
|
||||
let r = p.value().as_record(None).unwrap();
|
||||
match r.label().value().as_symbol().unwrap().as_ref() {
|
||||
"named" => {
|
||||
let dest = simple_pattern_parser(ctxt, &r.fields()[1], src, sequence_base, body).unwrap();
|
||||
let capture_expr = store_wrap(&field_type(&r.fields()[1]).unwrap().unwrap(), &dest);
|
||||
ctxt.capture(&names::render_fieldname(r.fields()[0].value().as_symbol().unwrap()),
|
||||
&capture_expr);
|
||||
Some(dest)
|
||||
}
|
||||
"rec" => {
|
||||
let rtmp = ctxt.gentempname();
|
||||
push_let(body, &rtmp, item(seq![src.to_owned(), ".value().to_record(None).map_err(|_| ())?"]));
|
||||
pattern_parser(ctxt, &r.fields()[0], &format!("{}.label()", rtmp), None, body);
|
||||
pattern_parser(ctxt, &r.fields()[1], &format!("{}.fields()", rtmp), Some(0), body);
|
||||
None
|
||||
}
|
||||
"tuple" => {
|
||||
let (src, n) = sequenceify(ctxt, src, sequence_base, body);
|
||||
fixed_sequence_parser(ctxt, n, r.fields()[0].value().to_sequence().unwrap(), &src, body);
|
||||
None
|
||||
}
|
||||
"tuplePrefix" => {
|
||||
let (src, n) = sequenceify(ctxt, src, sequence_base, body);
|
||||
let fixed = r.fields()[0].value().to_sequence().unwrap();
|
||||
fixed_sequence_parser(ctxt, n, fixed, &src, body);
|
||||
pattern_parser(ctxt, &r.fields()[1], &src, Some(n + fixed.len()), body)
|
||||
}
|
||||
"dict" => {
|
||||
let dtmp = ctxt.gentempname();
|
||||
push_let(body, &dtmp, item(seq![src.to_owned(), ".value().to_dictionary().map_err(|_| ())?"]));
|
||||
for (key_lit, value_pat) in r.fields()[0].value().to_dictionary().unwrap() {
|
||||
let vtmp = ctxt.gentempname();
|
||||
push_let(body, &vtmp, item(seq![
|
||||
dtmp.to_owned(), ".get", parens![ctxt.m.define_literal(key_lit)],
|
||||
".ok_or(())?"]));
|
||||
pattern_parser(ctxt, value_pat, &vtmp, None, body);
|
||||
}
|
||||
None
|
||||
}
|
||||
_ => panic!("Unexpected compound"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
use crate::*;
|
||||
use crate::syntax::block::Emittable;
|
||||
use crate::syntax::block::constructors::*;
|
||||
use super::names;
|
||||
|
||||
use preserves::value::{IOValue, NestedValue};
|
||||
use preserves::error::Error;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum TDefinition {
|
||||
Union(Vec<(String, TSimple)>),
|
||||
Simple(TSimple),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum TSimple {
|
||||
Field(TField),
|
||||
Record(TRecord),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum TField {
|
||||
Unit,
|
||||
Array(Box<TField>),
|
||||
Set(Box<TField>),
|
||||
Map(Box<TField>, Box<TField>),
|
||||
Ref(Vec<String>),
|
||||
Base(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct TRecord(pub Vec<(String, TField)>);
|
||||
|
||||
pub fn definition_type(d: &IOValue) -> Result<TDefinition, Error> {
|
||||
if let Some(fs) = d.value().as_simple_record("or", Some(1)) {
|
||||
let mut entries = Vec::new();
|
||||
for e in fs[0].value().to_sequence()?.iter() {
|
||||
let e = e.value().to_sequence()?;
|
||||
entries.push((e[0].value().to_string()?.to_owned(), simple_type(&e[1])?));
|
||||
}
|
||||
Ok(TDefinition::Union(entries))
|
||||
} else if let Some(fs) = d.value().as_simple_record("and", Some(1)) {
|
||||
Ok(TDefinition::Simple(record_type(fs[0].value().to_sequence()?)?))
|
||||
} else {
|
||||
Ok(TDefinition::Simple(simple_type(d)?))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn simple_type(p: &IOValue) -> Result<TSimple, Error> {
|
||||
if let Some(t) = field_type(p)? {
|
||||
Ok(TSimple::Field(t))
|
||||
} else {
|
||||
record_type(&vec![p.clone()])
|
||||
}
|
||||
}
|
||||
|
||||
pub fn record_type(ps: &Vec<IOValue>) -> Result<TSimple, Error> {
|
||||
let fs = gather_fields(ps, Vec::new())?;
|
||||
if fs.is_empty() {
|
||||
Ok(TSimple::Field(TField::Unit))
|
||||
} else {
|
||||
Ok(TSimple::Record(TRecord(fs)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gather_fields(ps: &Vec<IOValue>, mut fs: Vec<(String, TField)>) ->
|
||||
Result<Vec<(String, TField)>, Error>
|
||||
{
|
||||
for p in ps.iter() {
|
||||
fs = gather_field(p, fs)?;
|
||||
}
|
||||
Ok(fs)
|
||||
}
|
||||
|
||||
pub fn gather_field(p: &IOValue, mut fs: Vec<(String, TField)>) ->
|
||||
Result<Vec<(String, TField)>, Error>
|
||||
{
|
||||
if let Some(n) = p.value().as_simple_record("named", Some(2)) {
|
||||
let name = n[0].value().to_symbol()?;
|
||||
fs.push((name.to_owned(), field_type(&n[1])?.unwrap()));
|
||||
Ok(fs)
|
||||
} else if let Some(label_and_fields) = p.value().as_simple_record("rec", Some(2)) {
|
||||
Ok(gather_field(&label_and_fields[1], gather_field(&label_and_fields[0], fs)?)?)
|
||||
} else if let Some(tfs) = p.value().as_simple_record("tuple", Some(1)) {
|
||||
Ok(gather_fields(tfs[0].value().to_sequence()?, fs)?)
|
||||
} else if let Some(tfs) = p.value().as_simple_record("tuplePrefix", Some(2)) {
|
||||
Ok(gather_field(&tfs[1], gather_fields(tfs[0].value().to_sequence()?, fs)?)?)
|
||||
} else if let Some(dfs) = p.value().as_simple_record("dict", Some(1)) {
|
||||
let es = dfs[0].value().to_dictionary()?;
|
||||
for (_k, p) in es.iter() {
|
||||
fs = gather_field(p, fs)?;
|
||||
}
|
||||
Ok(fs)
|
||||
} else {
|
||||
Ok(fs)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn field_type(p: &IOValue) -> Result<Option<TField>, Error> {
|
||||
if p.value().as_symbol() == Some(&"any".to_owned()) {
|
||||
Ok(Some(TField::Base("preserves::value::IOValue".to_owned())))
|
||||
} else if let Some(fs) = p.value().as_simple_record("atom", Some(1)) {
|
||||
match fs[0].value().as_symbol().unwrap().as_str() {
|
||||
"Boolean" => Ok(Some(TField::Base("bool".to_owned()))),
|
||||
"Float" => Ok(Some(TField::Base("f32".to_owned()))),
|
||||
"Double" => Ok(Some(TField::Base("f64".to_owned()))),
|
||||
"SignedInteger" => Ok(Some(TField::Base("preserves::value::signed_integer::SignedInteger".to_owned()))),
|
||||
"String" => Ok(Some(TField::Base("std::string::String".to_owned()))),
|
||||
"ByteString" => Ok(Some(TField::Base("std::vec::Vec<u8>".to_owned()))),
|
||||
"Symbol" => Ok(Some(TField::Base("std::string::String".to_owned()))),
|
||||
_ => Err(Error::Message("Unexpected AtomKind".to_owned())),
|
||||
}
|
||||
} else if let Some(_) = p.value().as_simple_record("embedded", Some(1)) {
|
||||
Ok(Some(TField::Base("_ptr".to_owned())))
|
||||
} else if let Some(_) = p.value().as_simple_record("lit", Some(1)) {
|
||||
Ok(Some(TField::Unit))
|
||||
} else if let Some(fs) = p.value().as_simple_record("seqof", Some(1)) {
|
||||
Ok(Some(TField::Array(Box::new(field_type(&fs[0])?.unwrap()))))
|
||||
} else if let Some(fs) = p.value().as_simple_record("setof", Some(1)) {
|
||||
Ok(Some(TField::Set(Box::new(field_type(&fs[0])?.unwrap()))))
|
||||
} else if let Some(fs) = p.value().as_simple_record("dictof", Some(2)) {
|
||||
Ok(Some(TField::Map(Box::new(field_type(&fs[0])?.unwrap()),
|
||||
Box::new(field_type(&fs[1])?.unwrap()))))
|
||||
} else if let Some(fs) = p.value().as_simple_record("ref", Some(2)) {
|
||||
let mut pieces = fs[0].value().to_sequence()?.iter()
|
||||
.map(|v| v.value().to_symbol().map(String::to_owned))
|
||||
.collect::<Result<Vec<String>,_>>()?;
|
||||
pieces.push(fs[1].value().to_symbol()?.to_owned());
|
||||
Ok(Some(TField::Ref(pieces)))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_field_type(box_needed: bool, t: &TField) -> impl Emittable {
|
||||
match t {
|
||||
TField::Unit => seq!["()"],
|
||||
TField::Array(t) => seq!["std::vec::Vec<", render_field_type(false, t), ">"],
|
||||
TField::Set(t) => seq!["preserves::value::Set<", render_field_type(false, t), ">"],
|
||||
TField::Map(k, v) => seq!["preserves::value::Map",
|
||||
anglebrackets![render_field_type(false, k),
|
||||
render_field_type(false, v)]],
|
||||
TField::Ref(pieces) =>
|
||||
if box_needed {
|
||||
seq!["std::boxed::Box", anglebrackets![names::render_ref(pieces.clone())]]
|
||||
} else {
|
||||
seq![names::render_ref(pieces.clone())]
|
||||
},
|
||||
TField::Base(n) => seq![n.to_owned()],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_recordlike_type(is_struct: bool, n: &str, d: &TSimple) -> impl Emittable {
|
||||
let semi = if is_struct { seq![";"] } else { seq![] };
|
||||
seq![names::render_constructor(n), match d {
|
||||
TSimple::Record(TRecord(fs)) => seq![" ", braces(
|
||||
fs.iter().map(|(n, d)| item(
|
||||
seq![if is_struct { "pub " } else { "" },
|
||||
names::render_fieldname(n), ": ", render_field_type(true, d)]
|
||||
)).collect())],
|
||||
TSimple::Field(TField::Unit) => semi,
|
||||
TSimple::Field(t) => seq![parens![render_field_type(true, t)], semi],
|
||||
}]
|
||||
}
|
||||
|
||||
pub fn render_definition_type(n: &str, t: &TDefinition) -> impl Emittable {
|
||||
seq!["#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] ",
|
||||
match t {
|
||||
TDefinition::Union(items) =>
|
||||
seq!["pub enum ", names::render_constructor(n), " ", braces(
|
||||
items.iter().map(|(n, d)| item(render_recordlike_type(false, n, d))).collect())],
|
||||
TDefinition::Simple(s) =>
|
||||
seq!["pub struct ", render_recordlike_type(true, n, s)],
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
pub mod syntax;
|
||||
pub mod compiler;
|
||||
pub mod metaschema;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn can_access_preserves_core() {
|
||||
use preserves::value::*;
|
||||
assert_eq!(format!("{:?}", UnwrappedIOValue::from(3 + 4)), "7");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_rendering() {
|
||||
use crate::*;
|
||||
use crate::syntax::block::*;
|
||||
|
||||
let code = semiblock![
|
||||
seq!["f", parens!["a", "b", "c"]],
|
||||
seq!["f", parens!["a", "b", "c"]],
|
||||
seq!["f", parens!["a", "b", "c"]],
|
||||
seq!["f", parens!["a", "b", "c"]],
|
||||
seq!["f", parens!["a", "b", "c"]],
|
||||
seq!["f", parens!["a", "b", "c"]],
|
||||
seq!["g", parens![]],
|
||||
parens![]
|
||||
];
|
||||
println!("{}", Formatter::to_string(&code));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn metaschema_parsing() -> Result<(), std::io::Error> {
|
||||
use preserves::value::Reader;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
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));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,532 @@
|
|||
#![allow(unused_parens)]
|
||||
|
||||
use std::convert::TryFrom;
|
||||
use preserves::value::{NestedValue, Reader};
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref LIT15: preserves::value::IOValue = /* #f */ preserves::value::PackedReader::decode_bytes(&vec![128]).demand_next(false).unwrap();
|
||||
pub static ref LIT28: preserves::value::IOValue = /* 1 */ preserves::value::PackedReader::decode_bytes(&vec![145]).demand_next(false).unwrap();
|
||||
pub static ref LIT0: preserves::value::IOValue = /* Boolean */ preserves::value::PackedReader::decode_bytes(&vec![179, 7, 66, 111, 111, 108, 101, 97, 110]).demand_next(false).unwrap();
|
||||
pub static ref LIT5: preserves::value::IOValue = /* ByteString */ preserves::value::PackedReader::decode_bytes(&vec![179, 10, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103]).demand_next(false).unwrap();
|
||||
pub static ref LIT2: preserves::value::IOValue = /* Double */ preserves::value::PackedReader::decode_bytes(&vec![179, 6, 68, 111, 117, 98, 108, 101]).demand_next(false).unwrap();
|
||||
pub static ref LIT1: preserves::value::IOValue = /* Float */ preserves::value::PackedReader::decode_bytes(&vec![179, 5, 70, 108, 111, 97, 116]).demand_next(false).unwrap();
|
||||
pub static ref LIT3: preserves::value::IOValue = /* SignedInteger */ preserves::value::PackedReader::decode_bytes(&vec![179, 13, 83, 105, 103, 110, 101, 100, 73, 110, 116, 101, 103, 101, 114]).demand_next(false).unwrap();
|
||||
pub static ref LIT4: preserves::value::IOValue = /* String */ preserves::value::PackedReader::decode_bytes(&vec![179, 6, 83, 116, 114, 105, 110, 103]).demand_next(false).unwrap();
|
||||
pub static ref LIT6: preserves::value::IOValue = /* Symbol */ preserves::value::PackedReader::decode_bytes(&vec![179, 6, 83, 121, 109, 98, 111, 108]).demand_next(false).unwrap();
|
||||
pub static ref LIT14: preserves::value::IOValue = /* and */ preserves::value::PackedReader::decode_bytes(&vec![179, 3, 97, 110, 100]).demand_next(false).unwrap();
|
||||
pub static ref LIT21: preserves::value::IOValue = /* any */ preserves::value::PackedReader::decode_bytes(&vec![179, 3, 97, 110, 121]).demand_next(false).unwrap();
|
||||
pub static ref LIT22: preserves::value::IOValue = /* atom */ preserves::value::PackedReader::decode_bytes(&vec![179, 4, 97, 116, 111, 109]).demand_next(false).unwrap();
|
||||
pub static ref LIT8: preserves::value::IOValue = /* bundle */ preserves::value::PackedReader::decode_bytes(&vec![179, 6, 98, 117, 110, 100, 108, 101]).demand_next(false).unwrap();
|
||||
pub static ref LIT18: preserves::value::IOValue = /* definitions */ preserves::value::PackedReader::decode_bytes(&vec![179, 11, 100, 101, 102, 105, 110, 105, 116, 105, 111, 110, 115]).demand_next(false).unwrap();
|
||||
pub static ref LIT12: preserves::value::IOValue = /* dict */ preserves::value::PackedReader::decode_bytes(&vec![179, 4, 100, 105, 99, 116]).demand_next(false).unwrap();
|
||||
pub static ref LIT27: preserves::value::IOValue = /* dictof */ preserves::value::PackedReader::decode_bytes(&vec![179, 6, 100, 105, 99, 116, 111, 102]).demand_next(false).unwrap();
|
||||
pub static ref LIT23: preserves::value::IOValue = /* embedded */ preserves::value::PackedReader::decode_bytes(&vec![179, 8, 101, 109, 98, 101, 100, 100, 101, 100]).demand_next(false).unwrap();
|
||||
pub static ref LIT19: preserves::value::IOValue = /* embeddedType */ preserves::value::PackedReader::decode_bytes(&vec![179, 12, 101, 109, 98, 101, 100, 100, 101, 100, 84, 121, 112, 101]).demand_next(false).unwrap();
|
||||
pub static ref LIT24: preserves::value::IOValue = /* lit */ preserves::value::PackedReader::decode_bytes(&vec![179, 3, 108, 105, 116]).demand_next(false).unwrap();
|
||||
pub static ref LIT7: preserves::value::IOValue = /* named */ preserves::value::PackedReader::decode_bytes(&vec![179, 5, 110, 97, 109, 101, 100]).demand_next(false).unwrap();
|
||||
pub static ref LIT13: preserves::value::IOValue = /* or */ preserves::value::PackedReader::decode_bytes(&vec![179, 2, 111, 114]).demand_next(false).unwrap();
|
||||
pub static ref LIT9: preserves::value::IOValue = /* rec */ preserves::value::PackedReader::decode_bytes(&vec![179, 3, 114, 101, 99]).demand_next(false).unwrap();
|
||||
pub static ref LIT16: preserves::value::IOValue = /* ref */ preserves::value::PackedReader::decode_bytes(&vec![179, 3, 114, 101, 102]).demand_next(false).unwrap();
|
||||
pub static ref LIT17: preserves::value::IOValue = /* schema */ preserves::value::PackedReader::decode_bytes(&vec![179, 6, 115, 99, 104, 101, 109, 97]).demand_next(false).unwrap();
|
||||
pub static ref LIT25: preserves::value::IOValue = /* seqof */ preserves::value::PackedReader::decode_bytes(&vec![179, 5, 115, 101, 113, 111, 102]).demand_next(false).unwrap();
|
||||
pub static ref LIT26: preserves::value::IOValue = /* setof */ preserves::value::PackedReader::decode_bytes(&vec![179, 5, 115, 101, 116, 111, 102]).demand_next(false).unwrap();
|
||||
pub static ref LIT10: preserves::value::IOValue = /* tuple */ preserves::value::PackedReader::decode_bytes(&vec![179, 5, 116, 117, 112, 108, 101]).demand_next(false).unwrap();
|
||||
pub static ref LIT11: preserves::value::IOValue = /* tuplePrefix */ preserves::value::PackedReader::decode_bytes(&vec![179, 11, 116, 117, 112, 108, 101, 80, 114, 101, 102, 105, 120]).demand_next(false).unwrap();
|
||||
pub static ref LIT20: preserves::value::IOValue = /* version */ preserves::value::PackedReader::decode_bytes(&vec![179, 7, 118, 101, 114, 115, 105, 111, 110]).demand_next(false).unwrap();
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub enum AtomKind {Boolean, Float, Double, SignedInteger, String, ByteString, Symbol}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct Binding {pub name: std::string::String, pub pattern: std::boxed::Box<SimplePattern>}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct Bundle {pub modules: std::boxed::Box<Modules>}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub enum CompoundPattern {
|
||||
Rec {label: std::boxed::Box<NamedPattern>, fields: std::boxed::Box<NamedPattern>},
|
||||
Tuple {patterns: std::vec::Vec<NamedPattern>},
|
||||
TuplePrefix {
|
||||
fixed: std::vec::Vec<NamedPattern>,
|
||||
variable: std::boxed::Box<NamedSimplePattern>
|
||||
},
|
||||
Dict {entries: std::boxed::Box<DictionaryEntries>}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub enum Definition {
|
||||
Or {
|
||||
pattern_0: std::boxed::Box<NamedAlternative>,
|
||||
pattern_1: std::boxed::Box<NamedAlternative>,
|
||||
pattern_n: std::vec::Vec<NamedAlternative>
|
||||
},
|
||||
And {
|
||||
pattern_0: std::boxed::Box<NamedPattern>,
|
||||
pattern_1: std::boxed::Box<NamedPattern>,
|
||||
pattern_n: std::vec::Vec<NamedPattern>
|
||||
},
|
||||
Pattern(std::boxed::Box<Pattern>)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct Definitions(preserves::value::Map<std::string::String, Definition>);
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct DictionaryEntries(preserves::value::Map<preserves::value::IOValue, NamedSimplePattern>);
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub enum EmbeddedTypeName {Ref(std::boxed::Box<Ref>), False}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct ModulePath(std::vec::Vec<std::string::String>);
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct Modules(preserves::value::Map<ModulePath, Schema>);
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct NamedAlternative {pub variant_label: std::string::String, pub pattern: std::boxed::Box<Pattern>}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub enum NamedPattern {Named(std::boxed::Box<Binding>), Anonymous(std::boxed::Box<Pattern>)}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub enum NamedSimplePattern {Named(std::boxed::Box<Binding>), Anonymous(std::boxed::Box<SimplePattern>)}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub enum Pattern {
|
||||
SimplePattern(std::boxed::Box<SimplePattern>),
|
||||
CompoundPattern(std::boxed::Box<CompoundPattern>)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct Ref {pub module: std::boxed::Box<ModulePath>, pub name: std::string::String}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct Schema {
|
||||
pub definitions: std::boxed::Box<Definitions>,
|
||||
pub embedded_type: std::boxed::Box<EmbeddedTypeName>,
|
||||
pub version: std::boxed::Box<Version>
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub enum SimplePattern {
|
||||
Any,
|
||||
Atom {atom_kind: std::boxed::Box<AtomKind>},
|
||||
Embedded {interface: std::boxed::Box<SimplePattern>},
|
||||
Lit {value: preserves::value::IOValue},
|
||||
Seqof {pattern: std::boxed::Box<SimplePattern>},
|
||||
Setof {pattern: std::boxed::Box<SimplePattern>},
|
||||
Dictof {key: std::boxed::Box<SimplePattern>, value: std::boxed::Box<SimplePattern>},
|
||||
Ref(std::boxed::Box<Ref>)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct Version;
|
||||
|
||||
fn _parse_atom_kind_boolean(value: &preserves::value::IOValue) -> std::result::Result<AtomKind, ()> {if value != &*LIT0 { return Err(()); } let _tmp0 = (); Ok(AtomKind::Boolean)}
|
||||
|
||||
fn _parse_atom_kind_float(value: &preserves::value::IOValue) -> std::result::Result<AtomKind, ()> {if value != &*LIT1 { return Err(()); } let _tmp0 = (); Ok(AtomKind::Float)}
|
||||
|
||||
fn _parse_atom_kind_double(value: &preserves::value::IOValue) -> std::result::Result<AtomKind, ()> {if value != &*LIT2 { return Err(()); } let _tmp0 = (); Ok(AtomKind::Double)}
|
||||
|
||||
fn _parse_atom_kind_signed_integer(value: &preserves::value::IOValue) -> std::result::Result<AtomKind, ()> {
|
||||
if value != &*LIT3 { return Err(()); }
|
||||
let _tmp0 = ();
|
||||
Ok(AtomKind::SignedInteger)
|
||||
}
|
||||
|
||||
fn _parse_atom_kind_string(value: &preserves::value::IOValue) -> std::result::Result<AtomKind, ()> {if value != &*LIT4 { return Err(()); } let _tmp0 = (); Ok(AtomKind::String)}
|
||||
|
||||
fn _parse_atom_kind_byte_string(value: &preserves::value::IOValue) -> std::result::Result<AtomKind, ()> {
|
||||
if value != &*LIT5 { return Err(()); }
|
||||
let _tmp0 = ();
|
||||
Ok(AtomKind::ByteString)
|
||||
}
|
||||
|
||||
fn _parse_atom_kind_symbol(value: &preserves::value::IOValue) -> std::result::Result<AtomKind, ()> {if value != &*LIT6 { return Err(()); } let _tmp0 = (); Ok(AtomKind::Symbol)}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for AtomKind {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
if let Ok(r) = _parse_atom_kind_boolean(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_atom_kind_float(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_atom_kind_double(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_atom_kind_signed_integer(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_atom_kind_string(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_atom_kind_byte_string(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_atom_kind_symbol(value) { return Ok(r); }
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for Binding {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT7 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 2 { return Err(()); }
|
||||
let _tmp5 = (&_tmp1.fields()[0]).value().to_symbol().map_err(|_| ())?;
|
||||
let _tmp7 = SimplePattern::try_from((&_tmp1.fields()[1]))?;
|
||||
Ok(Binding {name: _tmp5.clone(), pattern: std::boxed::Box::new(_tmp7)})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for Bundle {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT8 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
|
||||
let _tmp5 = Modules::try_from((&_tmp1.fields()[0]))?;
|
||||
Ok(Bundle {modules: std::boxed::Box::new(_tmp5)})
|
||||
}
|
||||
}
|
||||
|
||||
fn _parse_compound_pattern_rec(value: &preserves::value::IOValue) -> std::result::Result<CompoundPattern, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT9 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 2 { return Err(()); }
|
||||
let _tmp5 = NamedPattern::try_from((&_tmp1.fields()[0]))?;
|
||||
let _tmp7 = NamedPattern::try_from((&_tmp1.fields()[1]))?;
|
||||
Ok(CompoundPattern::Rec {label: std::boxed::Box::new(_tmp5), fields: std::boxed::Box::new(_tmp7)})
|
||||
}
|
||||
|
||||
fn _parse_compound_pattern_tuple(value: &preserves::value::IOValue) -> std::result::Result<CompoundPattern, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT10 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
|
||||
let _tmp6 = (&_tmp1.fields()[0]).value().to_sequence().map_err(|_| ())?;
|
||||
let mut _tmp5 = std::vec::Vec::new();
|
||||
for _tmp7 in &_tmp6[0..] {let _tmp8 = NamedPattern::try_from(_tmp7)?; _tmp5.push(_tmp8);}
|
||||
Ok(CompoundPattern::Tuple {patterns: _tmp5})
|
||||
}
|
||||
|
||||
fn _parse_compound_pattern_tuple_prefix(value: &preserves::value::IOValue) -> std::result::Result<CompoundPattern, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT11 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 2 { return Err(()); }
|
||||
let _tmp6 = (&_tmp1.fields()[0]).value().to_sequence().map_err(|_| ())?;
|
||||
let mut _tmp5 = std::vec::Vec::new();
|
||||
for _tmp7 in &_tmp6[0..] {let _tmp8 = NamedPattern::try_from(_tmp7)?; _tmp5.push(_tmp8);}
|
||||
let _tmp10 = NamedSimplePattern::try_from((&_tmp1.fields()[1]))?;
|
||||
Ok(CompoundPattern::TuplePrefix {fixed: _tmp5, variable: std::boxed::Box::new(_tmp10)})
|
||||
}
|
||||
|
||||
fn _parse_compound_pattern_dict(value: &preserves::value::IOValue) -> std::result::Result<CompoundPattern, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT12 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
|
||||
let _tmp5 = DictionaryEntries::try_from((&_tmp1.fields()[0]))?;
|
||||
Ok(CompoundPattern::Dict {entries: std::boxed::Box::new(_tmp5)})
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for CompoundPattern {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
if let Ok(r) = _parse_compound_pattern_rec(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_compound_pattern_tuple(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_compound_pattern_tuple_prefix(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_compound_pattern_dict(value) { return Ok(r); }
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
fn _parse_definition_or(value: &preserves::value::IOValue) -> std::result::Result<Definition, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT13 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
|
||||
let _tmp5 = (&_tmp1.fields()[0]).value().to_sequence().map_err(|_| ())?;
|
||||
if _tmp5.len() - 0 < 2 { return Err(()); }
|
||||
let _tmp7 = NamedAlternative::try_from((&_tmp5[0]))?;
|
||||
let _tmp9 = NamedAlternative::try_from((&_tmp5[1]))?;
|
||||
let mut _tmp11 = std::vec::Vec::new();
|
||||
for _tmp12 in &_tmp5[2..] {let _tmp13 = NamedAlternative::try_from(_tmp12)?; _tmp11.push(_tmp13);}
|
||||
Ok(Definition::Or {
|
||||
pattern_0: std::boxed::Box::new(_tmp7),
|
||||
pattern_1: std::boxed::Box::new(_tmp9),
|
||||
pattern_n: _tmp11
|
||||
})
|
||||
}
|
||||
|
||||
fn _parse_definition_and(value: &preserves::value::IOValue) -> std::result::Result<Definition, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT14 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
|
||||
let _tmp5 = (&_tmp1.fields()[0]).value().to_sequence().map_err(|_| ())?;
|
||||
if _tmp5.len() - 0 < 2 { return Err(()); }
|
||||
let _tmp7 = NamedPattern::try_from((&_tmp5[0]))?;
|
||||
let _tmp9 = NamedPattern::try_from((&_tmp5[1]))?;
|
||||
let mut _tmp11 = std::vec::Vec::new();
|
||||
for _tmp12 in &_tmp5[2..] {let _tmp13 = NamedPattern::try_from(_tmp12)?; _tmp11.push(_tmp13);}
|
||||
Ok(Definition::And {
|
||||
pattern_0: std::boxed::Box::new(_tmp7),
|
||||
pattern_1: std::boxed::Box::new(_tmp9),
|
||||
pattern_n: _tmp11
|
||||
})
|
||||
}
|
||||
|
||||
fn _parse_definition_pattern(value: &preserves::value::IOValue) -> std::result::Result<Definition, ()> {
|
||||
let _tmp0 = Pattern::try_from(value)?;
|
||||
Ok(Definition::Pattern(std::boxed::Box::new(_tmp0)))
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for Definition {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
if let Ok(r) = _parse_definition_or(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_definition_and(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_definition_pattern(value) { return Ok(r); }
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for Definitions {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
let mut _tmp0 = preserves::value::Map::new();
|
||||
for (_tmp1, _tmp2) in value.value().to_dictionary().map_err(|_| ())? {
|
||||
let _tmp3 = _tmp1.value().to_symbol().map_err(|_| ())?;
|
||||
let _tmp4 = Definition::try_from(_tmp2)?;
|
||||
_tmp0.insert(_tmp3.clone(), _tmp4);
|
||||
}
|
||||
Ok(Definitions(_tmp0))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for DictionaryEntries {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
let mut _tmp0 = preserves::value::Map::new();
|
||||
for (_tmp1, _tmp2) in value.value().to_dictionary().map_err(|_| ())? {
|
||||
let _tmp3 = _tmp1;
|
||||
let _tmp4 = NamedSimplePattern::try_from(_tmp2)?;
|
||||
_tmp0.insert(_tmp3.clone(), _tmp4);
|
||||
}
|
||||
Ok(DictionaryEntries(_tmp0))
|
||||
}
|
||||
}
|
||||
|
||||
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)))
|
||||
}
|
||||
|
||||
fn _parse_embedded_type_name_false(value: &preserves::value::IOValue) -> std::result::Result<EmbeddedTypeName, ()> {
|
||||
if value != &*LIT15 { return Err(()); }
|
||||
let _tmp0 = ();
|
||||
Ok(EmbeddedTypeName::False)
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for EmbeddedTypeName {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
if let Ok(r) = _parse_embedded_type_name_ref(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_embedded_type_name_false(value) { return Ok(r); }
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for ModulePath {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
let _tmp1 = value.value().to_sequence().map_err(|_| ())?;
|
||||
let mut _tmp0 = std::vec::Vec::new();
|
||||
for _tmp2 in &_tmp1[0..] {
|
||||
let _tmp3 = _tmp2.value().to_symbol().map_err(|_| ())?;
|
||||
_tmp0.push(_tmp3.clone());
|
||||
}
|
||||
Ok(ModulePath(_tmp0))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for Modules {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
let mut _tmp0 = preserves::value::Map::new();
|
||||
for (_tmp1, _tmp2) in value.value().to_dictionary().map_err(|_| ())? {
|
||||
let _tmp3 = ModulePath::try_from(_tmp1)?;
|
||||
let _tmp4 = Schema::try_from(_tmp2)?;
|
||||
_tmp0.insert(_tmp3, _tmp4);
|
||||
}
|
||||
Ok(Modules(_tmp0))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for NamedAlternative {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
let _tmp1 = value.value().to_sequence().map_err(|_| ())?;
|
||||
if _tmp1.len() - 0 < 2 { return Err(()); }
|
||||
let _tmp3 = (&_tmp1[0]).value().to_string().map_err(|_| ())?;
|
||||
let _tmp5 = Pattern::try_from((&_tmp1[1]))?;
|
||||
Ok(NamedAlternative {variant_label: _tmp3.clone(), pattern: std::boxed::Box::new(_tmp5)})
|
||||
}
|
||||
}
|
||||
|
||||
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)))
|
||||
}
|
||||
|
||||
fn _parse_named_pattern_anonymous(value: &preserves::value::IOValue) -> std::result::Result<NamedPattern, ()> {
|
||||
let _tmp0 = Pattern::try_from(value)?;
|
||||
Ok(NamedPattern::Anonymous(std::boxed::Box::new(_tmp0)))
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for NamedPattern {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
if let Ok(r) = _parse_named_pattern_named(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_named_pattern_anonymous(value) { return Ok(r); }
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
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)))
|
||||
}
|
||||
|
||||
fn _parse_named_simple_pattern_anonymous(value: &preserves::value::IOValue) -> std::result::Result<NamedSimplePattern, ()> {
|
||||
let _tmp0 = SimplePattern::try_from(value)?;
|
||||
Ok(NamedSimplePattern::Anonymous(std::boxed::Box::new(_tmp0)))
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for NamedSimplePattern {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
if let Ok(r) = _parse_named_simple_pattern_named(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_named_simple_pattern_anonymous(value) { return Ok(r); }
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
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)))
|
||||
}
|
||||
|
||||
fn _parse_pattern_compound_pattern(value: &preserves::value::IOValue) -> std::result::Result<Pattern, ()> {
|
||||
let _tmp0 = CompoundPattern::try_from(value)?;
|
||||
Ok(Pattern::CompoundPattern(std::boxed::Box::new(_tmp0)))
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for Pattern {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
if let Ok(r) = _parse_pattern_simple_pattern(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_pattern_compound_pattern(value) { return Ok(r); }
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for Ref {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT16 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 2 { return Err(()); }
|
||||
let _tmp5 = ModulePath::try_from((&_tmp1.fields()[0]))?;
|
||||
let _tmp7 = (&_tmp1.fields()[1]).value().to_symbol().map_err(|_| ())?;
|
||||
Ok(Ref {module: std::boxed::Box::new(_tmp5), name: _tmp7.clone()})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for Schema {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT17 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
|
||||
let _tmp5 = (&_tmp1.fields()[0]).value().to_dictionary().map_err(|_| ())?;
|
||||
let _tmp6 = _tmp5.get(&*LIT18).ok_or(())?;
|
||||
let _tmp8 = Definitions::try_from(_tmp6)?;
|
||||
let _tmp9 = _tmp5.get(&*LIT19).ok_or(())?;
|
||||
let _tmp11 = EmbeddedTypeName::try_from(_tmp9)?;
|
||||
let _tmp12 = _tmp5.get(&*LIT20).ok_or(())?;
|
||||
let _tmp14 = Version::try_from(_tmp12)?;
|
||||
Ok(Schema {
|
||||
definitions: std::boxed::Box::new(_tmp8),
|
||||
embedded_type: std::boxed::Box::new(_tmp11),
|
||||
version: std::boxed::Box::new(_tmp14)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT22 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
|
||||
let _tmp5 = AtomKind::try_from((&_tmp1.fields()[0]))?;
|
||||
Ok(SimplePattern::Atom {atom_kind: std::boxed::Box::new(_tmp5)})
|
||||
}
|
||||
|
||||
fn _parse_simple_pattern_embedded(value: &preserves::value::IOValue) -> std::result::Result<SimplePattern, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT23 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
|
||||
let _tmp5 = SimplePattern::try_from((&_tmp1.fields()[0]))?;
|
||||
Ok(SimplePattern::Embedded {interface: std::boxed::Box::new(_tmp5)})
|
||||
}
|
||||
|
||||
fn _parse_simple_pattern_lit(value: &preserves::value::IOValue) -> std::result::Result<SimplePattern, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT24 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
|
||||
let _tmp5 = (&_tmp1.fields()[0]);
|
||||
Ok(SimplePattern::Lit {value: _tmp5.clone()})
|
||||
}
|
||||
|
||||
fn _parse_simple_pattern_seqof(value: &preserves::value::IOValue) -> std::result::Result<SimplePattern, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT25 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
|
||||
let _tmp5 = SimplePattern::try_from((&_tmp1.fields()[0]))?;
|
||||
Ok(SimplePattern::Seqof {pattern: std::boxed::Box::new(_tmp5)})
|
||||
}
|
||||
|
||||
fn _parse_simple_pattern_setof(value: &preserves::value::IOValue) -> std::result::Result<SimplePattern, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT26 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
|
||||
let _tmp5 = SimplePattern::try_from((&_tmp1.fields()[0]))?;
|
||||
Ok(SimplePattern::Setof {pattern: std::boxed::Box::new(_tmp5)})
|
||||
}
|
||||
|
||||
fn _parse_simple_pattern_dictof(value: &preserves::value::IOValue) -> std::result::Result<SimplePattern, ()> {
|
||||
let _tmp1 = value.value().to_record(None).map_err(|_| ())?;
|
||||
if _tmp1.label() != &*LIT27 { return Err(()); }
|
||||
let _tmp2 = ();
|
||||
if _tmp1.fields().len() - 0 < 2 { return Err(()); }
|
||||
let _tmp5 = SimplePattern::try_from((&_tmp1.fields()[0]))?;
|
||||
let _tmp7 = SimplePattern::try_from((&_tmp1.fields()[1]))?;
|
||||
Ok(SimplePattern::Dictof {key: std::boxed::Box::new(_tmp5), value: std::boxed::Box::new(_tmp7)})
|
||||
}
|
||||
|
||||
fn _parse_simple_pattern_ref(value: &preserves::value::IOValue) -> std::result::Result<SimplePattern, ()> {
|
||||
let _tmp0 = Ref::try_from(value)?;
|
||||
Ok(SimplePattern::Ref(std::boxed::Box::new(_tmp0)))
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<&preserves::value::IOValue> for SimplePattern {
|
||||
type Error = ();
|
||||
fn try_from(value: &preserves::value::IOValue) -> std::result::Result<Self, Self::Error> {
|
||||
if let Ok(r) = _parse_simple_pattern_any(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_simple_pattern_atom(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_simple_pattern_embedded(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_simple_pattern_lit(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_simple_pattern_seqof(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_simple_pattern_setof(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_simple_pattern_dictof(value) { return Ok(r); }
|
||||
if let Ok(r) = _parse_simple_pattern_ref(value) { return Ok(r); }
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
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)}
|
||||
}
|
||||
|
|
@ -0,0 +1,274 @@
|
|||
use std::str;
|
||||
|
||||
pub const DEFAULT_WIDTH: usize = 80;
|
||||
|
||||
pub trait Emittable: std::fmt::Debug {
|
||||
fn write_on(&self, f: &mut Formatter);
|
||||
}
|
||||
|
||||
pub type Item = std::rc::Rc<dyn Emittable>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Sequence {
|
||||
pub items: Vec<Item>,
|
||||
pub separator: &'static str,
|
||||
pub terminator: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Grouping {
|
||||
pub sequence: Sequence,
|
||||
pub open: &'static str,
|
||||
pub close: &'static str,
|
||||
}
|
||||
|
||||
pub struct Formatter {
|
||||
pub width: usize,
|
||||
indent_delta: String,
|
||||
current_indent: String,
|
||||
pub buffer: String,
|
||||
}
|
||||
|
||||
impl Formatter {
|
||||
pub fn new() -> Self {
|
||||
Formatter {
|
||||
width: DEFAULT_WIDTH,
|
||||
indent_delta: " ".to_owned(),
|
||||
current_indent: "\n".to_owned(),
|
||||
buffer: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_empty(&self) -> Formatter {
|
||||
Formatter {
|
||||
width: self.width,
|
||||
indent_delta: self.indent_delta.clone(),
|
||||
current_indent: self.current_indent.clone(),
|
||||
buffer: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn indent_size(self) -> usize {
|
||||
self.indent_delta.len()
|
||||
}
|
||||
|
||||
pub fn set_indent_size(&mut self, n: usize) {
|
||||
self.indent_delta = str::repeat(" ", n)
|
||||
}
|
||||
|
||||
pub fn write<E: Emittable>(&mut self, e: E) {
|
||||
e.write_on(self)
|
||||
}
|
||||
|
||||
pub fn newline(&mut self) {
|
||||
self.buffer.push_str(&self.current_indent)
|
||||
}
|
||||
|
||||
pub fn to_string<E: Emittable>(e: E) -> String {
|
||||
let mut f = Formatter::new();
|
||||
f.write(e);
|
||||
f.buffer
|
||||
}
|
||||
|
||||
pub fn with_indent<R, F: FnOnce(&mut Self) -> R>(&mut self, f: F) -> R {
|
||||
let old_indent = self.current_indent.clone();
|
||||
self.current_indent += &self.indent_delta;
|
||||
let r = f(self);
|
||||
self.current_indent = old_indent;
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
impl Emittable for &str {
|
||||
fn write_on(&self, f: &mut Formatter) {
|
||||
f.buffer.push_str(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Emittable for String {
|
||||
fn write_on(&self, f: &mut Formatter) {
|
||||
f.write(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: Emittable> Emittable for &'a Vec<E> where &'a E: Emittable {
|
||||
fn write_on(&self, f: &mut Formatter) {
|
||||
for e in self.iter() {
|
||||
f.write(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Emittable for Sequence {
|
||||
fn write_on(&self, f: &mut Formatter) {
|
||||
let mut need_sep = false;
|
||||
for e in self.items.iter() {
|
||||
if need_sep {
|
||||
self.separator.write_on(f)
|
||||
} else {
|
||||
need_sep = true
|
||||
}
|
||||
e.write_on(f)
|
||||
}
|
||||
self.terminator.write_on(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Emittable for Grouping {
|
||||
fn write_on(&self, f: &mut Formatter) {
|
||||
let mut g = f.copy_empty();
|
||||
self.open.write_on(&mut g);
|
||||
g.write(&self.sequence);
|
||||
self.close.write_on(&mut g);
|
||||
let s = g.buffer;
|
||||
if s.len() <= f.width {
|
||||
f.write(&s)
|
||||
} else {
|
||||
self.open.write_on(f);
|
||||
if !self.sequence.items.is_empty() {
|
||||
f.with_indent(|f| {
|
||||
let mut i = self.sequence.items.len();
|
||||
for e in self.sequence.items.iter() {
|
||||
f.newline();
|
||||
e.write_on(f);
|
||||
let delim = if i == 1 { self.sequence.terminator } else { self.sequence.separator };
|
||||
delim.trim_end().write_on(f);
|
||||
i = i - 1;
|
||||
}
|
||||
});
|
||||
f.newline()
|
||||
}
|
||||
self.close.write_on(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: Emittable> Emittable for &'a E {
|
||||
fn write_on(&self, f: &mut Formatter) {
|
||||
(*self).write_on(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Emittable for Item {
|
||||
fn write_on(&self, f: &mut Formatter) {
|
||||
(**self).write_on(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Sequence {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
f.write_str(&Formatter::to_string(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Grouping {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
f.write_str(&Formatter::to_string(self))
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
pub mod constructors {
|
||||
use super::Sequence;
|
||||
use super::Grouping;
|
||||
use super::Item;
|
||||
use super::Emittable;
|
||||
|
||||
pub fn item<E: 'static + Emittable>(i: E) -> Item {
|
||||
std::rc::Rc::new(i)
|
||||
}
|
||||
|
||||
pub fn name(pieces: Vec<Item>) -> Sequence {
|
||||
Sequence { items: pieces, separator: "::", terminator: "" }
|
||||
}
|
||||
|
||||
pub fn seq(items: Vec<Item>) -> Sequence {
|
||||
Sequence { items: items, separator: "", terminator: "" }
|
||||
}
|
||||
|
||||
pub fn commas(items: Vec<Item>) -> Sequence {
|
||||
Sequence { items: items, separator: ", ", terminator: "" }
|
||||
}
|
||||
|
||||
pub fn parens(items: Vec<Item>) -> Grouping {
|
||||
Grouping { sequence: commas(items), open: "(", close: ")" }
|
||||
}
|
||||
|
||||
pub fn brackets(items: Vec<Item>) -> Grouping {
|
||||
Grouping { sequence: commas(items), open: "[", close: "]" }
|
||||
}
|
||||
|
||||
pub fn anglebrackets(items: Vec<Item>) -> Grouping {
|
||||
Grouping { sequence: commas(items), open: "<", close: ">" }
|
||||
}
|
||||
|
||||
pub fn braces(items: Vec<Item>) -> Grouping {
|
||||
Grouping { sequence: commas(items), open: "{", close: "}" }
|
||||
}
|
||||
|
||||
pub fn block(items: Vec<Item>) -> Grouping {
|
||||
Grouping {
|
||||
sequence: Sequence { items: items, separator: " ", terminator: "" },
|
||||
open: "{",
|
||||
close: "}",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn semiblock(items: Vec<Item>) -> Grouping {
|
||||
Grouping {
|
||||
sequence: Sequence { items: items, separator: "; ", terminator: "" },
|
||||
open: "{",
|
||||
close: "}",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod macros {
|
||||
#[macro_export]
|
||||
macro_rules! name {
|
||||
($($item:expr),*) => {crate::syntax::block::constructors::name(vec![$(std::rc::Rc::new($item)),*])}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! seq {
|
||||
($($item:expr),*) => {crate::syntax::block::constructors::seq(vec![$(std::rc::Rc::new($item)),*])}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! commas {
|
||||
($($item:expr),*) => {crate::syntax::block::constructors::commas(vec![$(std::rc::Rc::new($item)),*])}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! parens {
|
||||
($($item:expr),*) => {crate::syntax::block::constructors::parens(vec![$(std::rc::Rc::new($item)),*])}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! brackets {
|
||||
($($item:expr),*) => {crate::syntax::block::constructors::brackets(vec![$(std::rc::Rc::new($item)),*])}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! anglebrackets {
|
||||
($($item:expr),*) => {crate::syntax::block::constructors::anglebrackets(vec![$(std::rc::Rc::new($item)),*])}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! braces {
|
||||
($($item:expr),*) => {crate::syntax::block::constructors::braces(vec![$(std::rc::Rc::new($item)),*])}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! block {
|
||||
($($item:expr),*) => {crate::syntax::block::constructors::block(vec![$(std::rc::Rc::new($item)),*])}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! semiblock {
|
||||
($($item:expr),*) => {crate::syntax::block::constructors::semiblock(vec![$(std::rc::Rc::new($item)),*])}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod block;
|
|
@ -21,6 +21,7 @@ pub use repr::Map;
|
|||
pub use repr::NestedValue;
|
||||
pub use repr::PlainValue;
|
||||
pub use repr::RcValue;
|
||||
pub use repr::Record;
|
||||
pub use repr::Set;
|
||||
pub use repr::UnwrappedIOValue;
|
||||
pub use repr::Value;
|
||||
|
|
|
@ -720,6 +720,22 @@ impl<N: NestedValue<D>, D: Domain> Value<N, D> {
|
|||
self.as_dictionary().ok_or_else(|| self.expected(ExpectedKind::Dictionary))
|
||||
}
|
||||
|
||||
pub fn is_embedded(&self) -> bool {
|
||||
self.as_embedded().is_some()
|
||||
}
|
||||
|
||||
pub fn as_embedded(&self) -> Option<&D> {
|
||||
if let Value::Domain(ref d) = *self {
|
||||
Some(d)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_embedded(&self) -> Result<&D, Error> {
|
||||
self.as_embedded().ok_or_else(|| self.expected(ExpectedKind::Embedded))
|
||||
}
|
||||
|
||||
pub fn copy_via<M: NestedValue<E>, E: Domain, F>(&self, f: &F) -> Value<M, E>
|
||||
where
|
||||
F: Fn(&D) -> Value<M, E>
|
||||
|
|
Loading…
Reference in New Issue