forked from syndicate-lang/preserves
Fix multi-schema bundles after refactor
This commit is contained in:
parent
985a0b6795
commit
e56b62cfbb
|
@ -58,6 +58,11 @@ pub enum CaptureMode {
|
|||
Indefinite(Vec<Item>),
|
||||
}
|
||||
|
||||
pub enum RefRenderStyle {
|
||||
Bare,
|
||||
Qualified,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref ID_RE: regex::Regex = regex::Regex::new(r"^[a-zA-Z][a-zA-Z_0-9]*$").unwrap();
|
||||
}
|
||||
|
@ -74,7 +79,14 @@ impl<'b> BundleContext<'b> {
|
|||
}
|
||||
|
||||
pub fn type_for_name(&self, r: &Ref) -> Option<&types::TDefinition> {
|
||||
self.types.get(r)
|
||||
if r.module.0.is_empty() {
|
||||
panic!("BundleContext::type_for_name with module-relative ref {:?}", r);
|
||||
}
|
||||
let result = self.types.get(r);
|
||||
if result.is_none() && !self.config.module_aliases.contains_key(&r.module.0) {
|
||||
panic!("Attempted to lookup unknown type {:?}", r)
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn define_literal(&mut self, v: &IOValue) -> String {
|
||||
|
@ -138,7 +150,7 @@ impl<'m, 'b> ModuleContext<'m, 'b> {
|
|||
self.functiondefs.push(i)
|
||||
}
|
||||
|
||||
pub fn render_ref(&self, r: &Ref, with_generic_args: bool) -> Item {
|
||||
pub fn render_ref(&self, r: &Ref, style: RefRenderStyle) -> Item {
|
||||
let base = match self.bundle.config.module_aliases.get(&r.module.0) {
|
||||
None =>
|
||||
if r.module.0.is_empty() {
|
||||
|
@ -153,43 +165,32 @@ impl<'m, 'b> ModuleContext<'m, 'b> {
|
|||
Some(s) =>
|
||||
item(name![s.to_owned(), r.name.to_owned()])
|
||||
};
|
||||
if with_generic_args && self.ref_has_embedded(r) {
|
||||
item(seq![base, anglebrackets!["_Any"]])
|
||||
} else {
|
||||
base
|
||||
let q = self.ref_has_embedded(r);
|
||||
match style {
|
||||
RefRenderStyle::Bare =>
|
||||
base,
|
||||
RefRenderStyle::Qualified =>
|
||||
if q { item(seq![base, anglebrackets!["_Value"]]) } else { base },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn any_type(&self) -> &'static str {
|
||||
"_Any"
|
||||
}
|
||||
|
||||
pub fn qualify(&self, r: &Ref) -> Ref {
|
||||
if r.module.0.is_empty() {
|
||||
Ref { module: self.module_path.clone(), name: r.name.clone() }
|
||||
} else {
|
||||
r.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_for_name(&self, r: &Ref) -> Option<&types::TDefinition> {
|
||||
self.bundle.type_for_name(&self.qualify(r))
|
||||
"_Value"
|
||||
}
|
||||
|
||||
pub fn ref_has_embedded(&self, r: &Ref) -> bool {
|
||||
match self.type_for_name(r) {
|
||||
Some(ty) => ty.has_embedded(self),
|
||||
None => false, // TODO: should this be configurable?
|
||||
}
|
||||
let r = r.qualify(&self.module_path);
|
||||
self.bundle.type_for_name(&r).map(|ty| ty.has_embedded(self.bundle)).unwrap_or(false)
|
||||
// ^ TODO: should the "false" be configurable?
|
||||
}
|
||||
|
||||
pub fn literals_generic_decls(&self) -> Item {
|
||||
item(anglebrackets!["_Any: preserves::value::NestedValue"])
|
||||
item(anglebrackets!["_Value: preserves::value::NestedValue"])
|
||||
}
|
||||
|
||||
pub fn literals_generic_decls_with_defaults(&self) -> Item {
|
||||
item(anglebrackets![
|
||||
seq!["_Any: preserves::value::NestedValue = ",
|
||||
seq!["_Value: preserves::value::NestedValue = ",
|
||||
if self.schema.embedded_type == EmbeddedTypeName::False {
|
||||
"preserves::value::IOValue"
|
||||
} else {
|
||||
|
@ -198,11 +199,11 @@ impl<'m, 'b> ModuleContext<'m, 'b> {
|
|||
}
|
||||
|
||||
pub fn literals_generic_arg(&self) -> Item {
|
||||
item("<_Any>")
|
||||
item("<_Value>")
|
||||
}
|
||||
|
||||
pub fn literals_type(&self) -> Item {
|
||||
item(seq!["&", self.literals_base_type(), self.literals_generic_arg()])
|
||||
item(seq![self.literals_base_type(), self.literals_generic_arg()])
|
||||
}
|
||||
|
||||
pub fn literals_base_type(&self) -> Item {
|
||||
|
|
|
@ -6,8 +6,10 @@ pub mod types;
|
|||
pub mod unparsers;
|
||||
|
||||
use crate::*;
|
||||
use crate::support::Parse;
|
||||
use crate::compiler::context::*;
|
||||
use crate::gen::Literals;
|
||||
use crate::gen::schema;
|
||||
use crate::gen::schema::*;
|
||||
use crate::syntax::block::{Formatter, Item};
|
||||
use crate::syntax::block::constructors::*;
|
||||
|
@ -101,11 +103,13 @@ impl CompilerConfig {
|
|||
}
|
||||
|
||||
fn build_type_cache(&self) -> Map<Ref, types::TDefinition> {
|
||||
self.bundle.iter().flat_map(
|
||||
|(modpath, s)| s.definitions.0.iter().map(
|
||||
move |(name, def)| (Ref { module: ModulePath(modpath.clone()), name: name.clone() },
|
||||
types::definition_type(def))))
|
||||
.collect()
|
||||
self.bundle.iter().flat_map(|(modpath, s)| {
|
||||
let modpath = ModulePath(modpath.clone());
|
||||
s.definitions.0.iter().map(move |(name, def)| {
|
||||
let ty = types::definition_type(&modpath, name, def);
|
||||
(ty.self_ref.clone(), ty)
|
||||
})
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn generate_definition(
|
||||
|
@ -150,6 +154,16 @@ fn write_if_changed(output_path: &PathBuf, contents: &[u8]) -> io::Result<()> {
|
|||
f.write_all(contents)
|
||||
}
|
||||
|
||||
impl Ref {
|
||||
pub fn qualify(&self, default_module_path: &schema::ModulePath) -> Ref {
|
||||
if self.module.0.is_empty() {
|
||||
Ref { module: default_module_path.clone(), name: self.name.clone() }
|
||||
} else {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Schema {
|
||||
pub fn has_embedded_type(&self) -> bool {
|
||||
self.embedded_type != EmbeddedTypeName::False
|
||||
|
@ -194,6 +208,8 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
|
|||
"use std::convert::TryFrom;",
|
||||
format!("use {}::support as _support;", &config.support_crate),
|
||||
"use _support::Deserialize;",
|
||||
"use _support::Parse;",
|
||||
"use _support::Unparse;",
|
||||
"use _support::preserves;",
|
||||
"use preserves::value::Domain;",
|
||||
"use preserves::value::NestedValue;",
|
||||
|
|
|
@ -3,7 +3,10 @@ use crate::gen::schema::*;
|
|||
use crate::syntax::block::Item;
|
||||
use crate::syntax::block::constructors::*;
|
||||
|
||||
use super::context::{ModuleContextMode, ModuleContext, FunctionContext};
|
||||
use super::context::FunctionContext;
|
||||
use super::context::ModuleContext;
|
||||
use super::context::ModuleContextMode;
|
||||
use super::context::RefRenderStyle;
|
||||
use super::names;
|
||||
use super::types::*;
|
||||
|
||||
|
@ -19,7 +22,7 @@ impl compiler::Plugin for ParserPlugin {
|
|||
}
|
||||
|
||||
pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
|
||||
let ty = definition_type(d);
|
||||
let ty = definition_type(&m.module_path, n, d);
|
||||
|
||||
m.define_function(
|
||||
n,
|
||||
|
@ -41,7 +44,7 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
|
|||
let dest = dest.as_ref().map(String::as_str);
|
||||
construct(&ctxt, ctorname, false, &pattern_type(pat), dest, &mut body);
|
||||
item(seq!["fn ", fname.clone(), ctxt.m.literals_generic_decls(),
|
||||
"(_ctxt: ", ctxt.m.literals_type(), ", value: &", ctxt.m.any_type(), ") -> ",
|
||||
"(_ctxt: &", ctxt.m.literals_type(), ", value: &", ctxt.m.any_type(), ") -> ",
|
||||
"std::result::Result<",
|
||||
names::render_constructor(n), ty.generic_arg(ctxt.m),
|
||||
", _support::ParseError> ",
|
||||
|
@ -66,36 +69,16 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
|
|||
}
|
||||
}
|
||||
|
||||
let (topdecl, innerdecl) = if ty.has_embedded(ctxt.m) {
|
||||
(ctxt.m.literals_generic_decls(), item(""))
|
||||
} else {
|
||||
(item(""), ctxt.m.literals_generic_decls())
|
||||
};
|
||||
|
||||
item(seq!["impl", topdecl, " ",
|
||||
item(seq!["impl", ctxt.m.literals_generic_decls(),
|
||||
" _support::Parse", anglebrackets![ctxt.m.literals_type(),
|
||||
ctxt.m.any_type()], " for ",
|
||||
names::render_constructor(n), ty.generic_arg(ctxt.m), " ",
|
||||
block![
|
||||
seq!["pub fn parse", innerdecl, "(_ctxt: ", ctxt.m.literals_type(),
|
||||
seq!["fn parse(_ctxt: &", ctxt.m.literals_type(),
|
||||
", value: &", ctxt.m.any_type(), ") -> ",
|
||||
"std::result::Result<Self, _support::ParseError> ",
|
||||
codeblock(body)]]])
|
||||
});
|
||||
|
||||
// m.define_function(
|
||||
// n,
|
||||
// |ctxt| {
|
||||
// item(seq!["impl", ctxt.m.literals_generic_decls(),
|
||||
// " std::convert::TryFrom", anglebrackets![seq!["&", ctxt.m.any_type()]], " for ",
|
||||
// names::render_constructor(n), ty.generic_arg(ctxt.m), " ",
|
||||
// block![
|
||||
// seq!["type Error = _support::ParseError;"],
|
||||
// seq!["fn try_from(value: &", ctxt.m.any_type(), ") -> ",
|
||||
// "std::result::Result<Self, _support::ParseError> ",
|
||||
// codeblock![
|
||||
// seq!["Self::parse(",
|
||||
// ctxt.m.literals_base_type(), "::default()",
|
||||
// ", value)"]]]]])
|
||||
// });
|
||||
}
|
||||
|
||||
fn construct(
|
||||
|
@ -214,7 +197,7 @@ fn simple_pattern_parser(
|
|||
dest
|
||||
},
|
||||
SimplePattern::Ref(r) => {
|
||||
let tf = name![ctxt.m.render_ref(&**r, false), "parse"];
|
||||
let tf = name![ctxt.m.render_ref(&**r, RefRenderStyle::Bare), "parse"];
|
||||
ctxt.define_atom(body,
|
||||
&dest,
|
||||
item(seq![tf, parens!["_ctxt", src.to_owned()], "?"]));
|
||||
|
|
|
@ -11,7 +11,10 @@ use preserves::value::IOValue;
|
|||
use preserves::value::NestedValue;
|
||||
use preserves::value::ValueClass;
|
||||
|
||||
use super::context::{ModuleContextMode, ModuleContext, FunctionContext};
|
||||
use super::context::FunctionContext;
|
||||
use super::context::ModuleContext;
|
||||
use super::context::ModuleContextMode;
|
||||
use super::context::RefRenderStyle;
|
||||
use super::names;
|
||||
use super::types::*;
|
||||
|
||||
|
@ -75,7 +78,7 @@ impl BoundaryTracker {
|
|||
}
|
||||
|
||||
pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) {
|
||||
let ty = definition_type(d);
|
||||
let ty = definition_type(&m.module_path, n, d);
|
||||
|
||||
m.define_function(
|
||||
n,
|
||||
|
@ -100,8 +103,8 @@ pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) {
|
|||
item(seq![
|
||||
"fn ", fname.clone(), anglebrackets![
|
||||
"'de",
|
||||
"_Any: preserves::value::NestedValue",
|
||||
"R: _support::Reader<'de, _Any>"],
|
||||
"_Value: preserves::value::NestedValue",
|
||||
"R: _support::Reader<'de, _Value>"],
|
||||
"(r: &mut R) -> ",
|
||||
"std::result::Result<",
|
||||
names::render_constructor(n), ty.generic_arg(ctxt.m),
|
||||
|
@ -139,9 +142,9 @@ pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) {
|
|||
|
||||
item(seq![
|
||||
"impl", anglebrackets!["'de",
|
||||
"_Any: preserves::value::NestedValue",
|
||||
"R: _support::Reader<'de, _Any>"], " ",
|
||||
"_support::Deserialize", anglebrackets!["'de", "_Any", "R"], " ",
|
||||
"_Value: preserves::value::NestedValue",
|
||||
"R: _support::Reader<'de, _Value>"], " ",
|
||||
"_support::Deserialize", anglebrackets!["'de", "_Value", "R"], " ",
|
||||
"for ", names::render_constructor(n), ty.generic_arg(ctxt.m), " ", block![
|
||||
seq!["fn deserialize(r: &mut R) -> ",
|
||||
"std::result::Result<Self, _support::ParseError> ",
|
||||
|
@ -426,7 +429,7 @@ fn simple_pattern_reader(
|
|||
dest
|
||||
},
|
||||
SimplePattern::Ref(r) => {
|
||||
let tf = name![ctxt.m.render_ref(&**r, false), "deserialize"];
|
||||
let tf = name![ctxt.m.render_ref(&**r, RefRenderStyle::Bare), "deserialize"];
|
||||
ctxt.define_atom(body, &dest, item(seq![tf, "(r)?"]));
|
||||
dest
|
||||
},
|
||||
|
|
|
@ -5,13 +5,22 @@ use crate::gen::schema::*;
|
|||
|
||||
use preserves::value::Set;
|
||||
|
||||
use super::context::{ModuleContextMode, ModuleContext};
|
||||
use super::context::BundleContext;
|
||||
use super::context::ModuleContext;
|
||||
use super::context::ModuleContextMode;
|
||||
use super::context::RefRenderStyle;
|
||||
use super::names;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum TDefinition {
|
||||
Union(Vec<(String, TSimple)>),
|
||||
Simple(TSimple),
|
||||
pub struct TDefinition {
|
||||
pub self_ref: Ref,
|
||||
pub body: TDefinitionBody,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum TDefinitionBody {
|
||||
Union(Vec<(String, TSimple)>),
|
||||
Simple(TSimple),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
|
@ -42,7 +51,7 @@ impl compiler::Plugin for TypePlugin {
|
|||
fn generate_module(&self, m: &mut ModuleContext) {
|
||||
if let EmbeddedTypeName::Ref(r) = &m.schema.embedded_type {
|
||||
m.define_type(item(vertical(false, seq![
|
||||
seq!["pub type _Dom = ", m.render_ref(&*r, true), ";"],
|
||||
seq!["pub type _Dom = ", m.render_ref(&*r, RefRenderStyle::Bare), ";"],
|
||||
seq!["pub type _Ptr = std::sync::Arc<_Dom>;"],
|
||||
seq!["pub type _Any = preserves::value::ArcValue<_Ptr>;"]
|
||||
])));
|
||||
|
@ -51,7 +60,7 @@ impl compiler::Plugin for TypePlugin {
|
|||
|
||||
fn generate_definition(&self, m: &mut ModuleContext, n: &str, d: &Definition) {
|
||||
if let ModuleContextMode::TargetGeneric = m.mode {
|
||||
let ty = definition_type(d);
|
||||
let ty = definition_type(&m.module_path, n, d);
|
||||
m.define_type(item(ty.render(m, n)));
|
||||
m.define_type(item(seq![
|
||||
"impl", ty.generic_decl(m), " preserves::value::Domain for ",
|
||||
|
@ -60,14 +69,17 @@ impl compiler::Plugin for TypePlugin {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn definition_type(d: &Definition) -> TDefinition {
|
||||
match d {
|
||||
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 definition_type(module: &ModulePath, n: &str, d: &Definition) -> TDefinition {
|
||||
TDefinition {
|
||||
self_ref: Ref { module: module.clone(), name: n.to_owned() },
|
||||
body: match d {
|
||||
Definition::Or { pattern_0, pattern_1, pattern_n } =>
|
||||
TDefinitionBody::Union(or_definition_type(pattern_0, pattern_1, pattern_n)),
|
||||
Definition::And { pattern_0, pattern_1, pattern_n } =>
|
||||
TDefinitionBody::Simple(and_definition_type(pattern_0, pattern_1, pattern_n)),
|
||||
Definition::Pattern(p) =>
|
||||
TDefinitionBody::Simple(pattern_type(p)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,8 +195,8 @@ impl TField {
|
|||
fn render(&self, ctxt: &ModuleContext, box_needed: bool) -> impl Emittable {
|
||||
match self {
|
||||
TField::Unit => seq!["()"],
|
||||
TField::Any => seq!["_Any"],
|
||||
TField::Embedded => seq!["_Ptr"],
|
||||
TField::Any => seq!["_Value"],
|
||||
TField::Embedded => seq!["_Value::D"],
|
||||
TField::Array(t) => seq!["std::vec::Vec<", t.render(ctxt, false), ">"],
|
||||
TField::Set(t) => seq!["preserves::value::Set<", t.render(ctxt, false), ">"],
|
||||
TField::Map(k, v) => seq!["preserves::value::Map",
|
||||
|
@ -192,29 +204,34 @@ impl TField {
|
|||
v.render(ctxt, false)]],
|
||||
TField::Ref(r) =>
|
||||
if box_needed {
|
||||
seq!["std::boxed::Box", anglebrackets![ctxt.render_ref(r, true)]]
|
||||
seq!["std::boxed::Box", anglebrackets![
|
||||
ctxt.render_ref(r, RefRenderStyle::Qualified)]]
|
||||
} else {
|
||||
seq![ctxt.render_ref(r, true)]
|
||||
seq![ctxt.render_ref(r, RefRenderStyle::Qualified)]
|
||||
},
|
||||
TField::Base(n) => seq![n.to_owned()],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_embedded(&self, ctxt: &ModuleContext, seen: &mut Set<Ref>) -> bool {
|
||||
pub fn has_embedded(&self, default_module_path: &ModulePath, ctxt: &BundleContext, seen: &mut Set<Ref>) -> bool {
|
||||
match self {
|
||||
TField::Unit => false,
|
||||
TField::Any => true, // at least potentially true
|
||||
TField::Embedded => true,
|
||||
TField::Array(f) => f.has_embedded(ctxt, seen),
|
||||
TField::Set(f) => f.has_embedded(ctxt, seen),
|
||||
TField::Map(k, v) => k.has_embedded(ctxt, seen) || v.has_embedded(ctxt, seen),
|
||||
TField::Array(f) => f.has_embedded(default_module_path, ctxt, seen),
|
||||
TField::Set(f) => f.has_embedded(default_module_path, ctxt, seen),
|
||||
TField::Map(k, v) =>
|
||||
k.has_embedded(default_module_path, ctxt, seen) ||
|
||||
v.has_embedded(default_module_path, ctxt, seen),
|
||||
TField::Ref(r) => {
|
||||
let r = ctxt.qualify(r);
|
||||
let r = r.qualify(default_module_path);
|
||||
if seen.contains(&r) {
|
||||
false
|
||||
} else {
|
||||
seen.insert(r.clone());
|
||||
ctxt.type_for_name(&r).map(|ty| ty._has_embedded(ctxt, seen)).unwrap_or(false)
|
||||
// ^ TODO: should the "false" be configurable?
|
||||
// cf. ModuleContext::ref_has_embedded.
|
||||
}
|
||||
}
|
||||
TField::Base(_) => false,
|
||||
|
@ -237,17 +254,19 @@ impl TSimple {
|
|||
}]
|
||||
}
|
||||
|
||||
pub fn has_embedded(&self, ctxt: &ModuleContext, seen: &mut Set<Ref>) -> bool {
|
||||
pub fn has_embedded(&self, default_module_path: &ModulePath, ctxt: &BundleContext, seen: &mut Set<Ref>) -> bool {
|
||||
match self {
|
||||
TSimple::Field(f) => f.has_embedded(ctxt, seen),
|
||||
TSimple::Record(TRecord(fs)) => fs.iter().any(|(_k, v)| v.has_embedded(ctxt, seen)),
|
||||
TSimple::Field(f) =>
|
||||
f.has_embedded(default_module_path, ctxt, seen),
|
||||
TSimple::Record(TRecord(fs)) =>
|
||||
fs.iter().any(|(_k, v)| v.has_embedded(default_module_path, ctxt, seen)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TDefinition {
|
||||
pub fn generic_decl(&self, ctxt: &ModuleContext) -> Item {
|
||||
if self.has_embedded(ctxt) {
|
||||
if self.has_embedded(ctxt.bundle) {
|
||||
ctxt.literals_generic_decls()
|
||||
} else {
|
||||
item("")
|
||||
|
@ -255,7 +274,7 @@ impl TDefinition {
|
|||
}
|
||||
|
||||
pub fn generic_decl_with_defaults(&self, ctxt: &ModuleContext) -> Item {
|
||||
if self.has_embedded(ctxt) {
|
||||
if self.has_embedded(ctxt.bundle) {
|
||||
ctxt.literals_generic_decls_with_defaults()
|
||||
} else {
|
||||
item("")
|
||||
|
@ -263,7 +282,7 @@ impl TDefinition {
|
|||
}
|
||||
|
||||
pub fn generic_arg(&self, ctxt: &ModuleContext) -> Item {
|
||||
if self.has_embedded(ctxt) {
|
||||
if self.has_embedded(ctxt.bundle) {
|
||||
ctxt.literals_generic_arg()
|
||||
} else {
|
||||
item("")
|
||||
|
@ -273,25 +292,27 @@ impl TDefinition {
|
|||
pub fn render(&self, ctxt: &ModuleContext, n: &str) -> impl Emittable {
|
||||
vertical(false, seq![
|
||||
"#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash)]",
|
||||
match self {
|
||||
TDefinition::Union(items) =>
|
||||
match &self.body {
|
||||
TDefinitionBody::Union(items) =>
|
||||
seq!["pub enum ",
|
||||
names::render_constructor(n), self.generic_decl_with_defaults(ctxt), " ",
|
||||
vertical(false, braces(items.iter().map(
|
||||
|(n, d)| item(d.render(ctxt, item(""), false, n))).collect()))],
|
||||
TDefinition::Simple(s) =>
|
||||
TDefinitionBody::Simple(s) =>
|
||||
seq!["pub struct ", s.render(ctxt, self.generic_decl_with_defaults(ctxt), true, n)],
|
||||
}])
|
||||
}
|
||||
|
||||
pub fn has_embedded(&self, ctxt: &ModuleContext) -> bool {
|
||||
pub fn has_embedded(&self, ctxt: &BundleContext) -> bool {
|
||||
self._has_embedded(ctxt, &mut Set::new())
|
||||
}
|
||||
|
||||
fn _has_embedded(&self, ctxt: &ModuleContext, seen: &mut Set<Ref>) -> bool {
|
||||
match self {
|
||||
TDefinition::Union(entries) => entries.iter().any(|(_k, v)| v.has_embedded(ctxt, seen)),
|
||||
TDefinition::Simple(t) => t.has_embedded(ctxt, seen),
|
||||
fn _has_embedded(&self, ctxt: &BundleContext, seen: &mut Set<Ref>) -> bool {
|
||||
match &self.body {
|
||||
TDefinitionBody::Union(entries) =>
|
||||
entries.iter().any(|(_k, v)| v.has_embedded(&self.self_ref.module, ctxt, seen)),
|
||||
TDefinitionBody::Simple(t) =>
|
||||
t.has_embedded(&self.self_ref.module, ctxt, seen),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ fn normal_src(src: String, is_struct: bool) -> ValueContext {
|
|||
}
|
||||
|
||||
pub fn gen_definition_unparser(m: &mut ModuleContext, n: &str, d: &Definition) {
|
||||
let ty = definition_type(d);
|
||||
let ty = definition_type(&m.module_path, n, d);
|
||||
|
||||
m.define_function(
|
||||
n,
|
||||
|
@ -97,17 +97,14 @@ pub fn gen_definition_unparser(m: &mut ModuleContext, n: &str, d: &Definition) {
|
|||
}
|
||||
}
|
||||
|
||||
let (topdecl, innerdecl) = if ty.has_embedded(ctxt.m) {
|
||||
(ctxt.m.literals_generic_decls(), item(""))
|
||||
} else {
|
||||
(item(""), ctxt.m.literals_generic_decls())
|
||||
};
|
||||
|
||||
item(seq!["impl", topdecl, " ",
|
||||
names::render_constructor(n), ty.generic_arg(ctxt.m), " ", block![
|
||||
seq!["pub fn unparse", innerdecl,
|
||||
"(&self, _ctxt: ", ctxt.m.literals_type(), ") -> ",
|
||||
ctxt.m.any_type(), " ", block(body)]]])
|
||||
item(seq!["impl", ctxt.m.literals_generic_decls(),
|
||||
" _support::Unparse", anglebrackets![ctxt.m.literals_type(),
|
||||
ctxt.m.any_type()], " for ",
|
||||
names::render_constructor(n), ty.generic_arg(ctxt.m), " ",
|
||||
block![
|
||||
seq!["fn unparse(&self, _ctxt: &", ctxt.m.literals_type(),
|
||||
") -> ", ctxt.m.any_type(), " ",
|
||||
block(body)]]])
|
||||
});
|
||||
|
||||
// m.define_function(
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,6 +3,12 @@ pub mod compiler;
|
|||
pub mod support;
|
||||
pub mod gen;
|
||||
|
||||
pub use support::Codec;
|
||||
pub use support::Deserialize;
|
||||
pub use support::Parse;
|
||||
pub use support::ParseError;
|
||||
pub use support::Unparse;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
|
@ -32,6 +38,8 @@ mod tests {
|
|||
#[test]
|
||||
fn metaschema_parsing() -> Result<(), std::io::Error> {
|
||||
use preserves::value::{BinarySource, IOBinarySource, Reader};
|
||||
use crate::Parse;
|
||||
use crate::Unparse;
|
||||
use crate::gen::schema::*;
|
||||
|
||||
let mut f = std::fs::File::open("../../../schema/schema.bin")?;
|
||||
|
|
|
@ -19,18 +19,46 @@ use std::sync::Arc;
|
|||
|
||||
use thiserror::Error;
|
||||
|
||||
pub struct Codec<N: NestedValue, L: Default> {
|
||||
pub trait Parse<L, Value: NestedValue>: Sized {
|
||||
fn parse(literals: &L, value: &Value) -> Result<Self, ParseError>;
|
||||
}
|
||||
|
||||
impl<L, Value: NestedValue> Parse<L, Value> for Value {
|
||||
fn parse(_literals: &L, value: &Value) -> Result<Self, ParseError> {
|
||||
Ok(value.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Unparse<L, Value: NestedValue> {
|
||||
fn unparse(&self, literals: &L) -> Value;
|
||||
}
|
||||
|
||||
impl<L, Value: NestedValue> Unparse<L, Value> for Value {
|
||||
fn unparse(&self, _literals: &L) -> Value {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Codec<L: Default, N: NestedValue> {
|
||||
pub literals: L,
|
||||
phantom: PhantomData<N>,
|
||||
}
|
||||
|
||||
impl<N: NestedValue, L: Default> Codec<N, L> {
|
||||
impl<L: Default, N: NestedValue> Codec<L, N> {
|
||||
pub fn new() -> Self {
|
||||
Codec {
|
||||
literals: L::default(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse<T: Parse<L, N>>(&self, value: &N) -> Result<T, ParseError> {
|
||||
T::parse(&self.literals, value)
|
||||
}
|
||||
|
||||
pub fn unparse<T: Unparse<L, N>>(&self, value: &T) -> N {
|
||||
value.unparse(&self.literals)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Deserialize<'de, N: NestedValue, R: Reader<'de, N>>
|
||||
|
|
Loading…
Reference in New Issue