Fixes in handling of embeddeds

This commit is contained in:
Tony Garnock-Jones 2021-07-03 23:11:41 +02:00
parent 83d15a838e
commit 64ff818cd1
6 changed files with 130 additions and 805 deletions

View File

@ -12,7 +12,6 @@ use crate::syntax::block::constructors::*;
use glob::glob;
use preserves::value::Map;
use preserves::value::NestedValue;
use preserves::value::PackedReader;
use preserves::value::Reader;
use preserves::value::Set;
@ -92,9 +91,6 @@ pub fn expand_inputs(globs: &Vec<String>) -> Result<Vec<PathBuf>, Error> {
}
pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
let modes: Vec<context::ModuleContextMode> =
vec![context::ModuleContextMode::TargetIOValue, context::ModuleContextMode::TargetAny];
for (k, v) in config.bundle.iter() {
let mut output_path = config.output_dir.clone();
output_path.extend(k);
@ -104,14 +100,28 @@ pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
DirBuilder::new().recursive(true).create(output_path.parent().unwrap())?;
let mut m = context::ModuleContext::new(config);
m.define_type(item(seq!["pub type _Ptr = ", match &v.embedded_type {
EmbeddedTypeName::False => item("preserves::value::IOValue".to_owned()),
EmbeddedTypeName::Ref(r) => item(seq!["std::sync::Arc", anglebrackets![m.render_ref(&**r)]]),
}, ";"]));
m.define_type(item(seq!["pub type _Any = preserves::value::ArcValue<_Ptr>;"]));
let mut modes: Vec<context::ModuleContextMode> =
vec![context::ModuleContextMode::TargetAny];
match &v.embedded_type {
EmbeddedTypeName::False => {
m.define_type(item(seq!["pub type _Ptr = preserves::value::IOValue;"]));
m.define_type(item(seq!["pub type _Any = preserves::value::IOValue;"]));
}
EmbeddedTypeName::Ref(r) => {
modes.push(context::ModuleContextMode::TargetIOValue);
m.define_type(item(seq!["pub type _Dom = ", m.render_ref(&**r), ";"]));
m.define_type(item(seq!["pub type _Ptr = std::sync::Arc<_Dom>;"]));
m.define_type(item(seq!["pub type _Any = preserves::value::ArcValue<_Ptr>;"]));
}
}
let modes = modes; // rebind as non-mutable
for (n, d) in &v.definitions.0 {
m.define_type(item(types::render_definition_type(&m, n, &types::definition_type(d))));
m.define_type(item(seq!["impl preserves::value::Domain for ",
names::render_constructor(n), " {}"]));
for mode in &modes {
m.mode = *mode;
parsers::gen_definition_parser(&mut m, n, d);
@ -136,18 +146,15 @@ pub fn compile(config: &CompilerConfig) -> Result<(), std::io::Error> {
m.mode = *mode;
lines.push(format!("mod {} {{", m.target_prefix()));
lines.push(" use super::_Any;".to_owned());
lines.push(" use preserves::value::NestedValue;".to_owned());
lines.push(" use preserves::value::packed::from_bytes;".to_owned());
lines.push(format!(" use {}::support as _support;", &config.support_crate));
lines.push(" _support::lazy_static! {".to_owned());
for (value, name) in &m.literals {
let bs = preserves::value::PackedWriter::encode(&value.to_io_value()).unwrap();
let bs = preserves::value::PackedWriter::encode(&value).unwrap();
lines.push(format!(
" pub static ref {}: {} = /* {:?} */ {}::from_io_value(&from_bytes(&vec!{:?}).unwrap()).unwrap();",
" pub static ref {}: {} = /* {:?} */ _support::decode_lit(&vec!{:?}).unwrap();",
name,
m.target(),
value,
m.target(),
bs));
}
lines.push(" }".to_owned());

View File

@ -108,7 +108,7 @@ fn simple_pattern_parser(
SimplePattern::Any => {
match ctxt.m.mode {
ModuleContextMode::TargetIOValue =>
push_let(body, item(dest.to_owned()), item(seq!["_Any::from_io_value", parens![src.to_owned()], "?"])),
push_let(body, item(dest.to_owned()), item(seq!["_support::decode_embedded", parens![src.to_owned()], "?"])),
ModuleContextMode::TargetAny =>
push_let(body, item(dest.to_owned()), item(src.to_owned())),
}
@ -131,9 +131,9 @@ fn simple_pattern_parser(
match ctxt.m.mode {
ModuleContextMode::TargetIOValue =>
push_let(body, item(dest.to_owned()), item(seq![
"_Ptr::from_preserves",
parens![seq![src.to_owned(), ".value().to_embedded()?", ".clone()"]],
"?"])),
"std::sync::Arc::new(_Dom::try_from",
parens![seq![src.to_owned(), ".value().to_embedded()?"]],
"?)"])),
ModuleContextMode::TargetAny =>
push_let(body, item(dest.to_owned()), item(seq![
parens![seq![src.to_owned(), ".value().to_embedded()?"]]])),

View File

@ -123,7 +123,7 @@ fn simple_pattern_unparser(
SimplePattern::Any => {
match ctxt.m.mode {
ModuleContextMode::TargetIOValue =>
item(seq![src.as_ref().unwrap().to_owned(), ".to_io_value()"]),
item(seq!["_support::encode_embedded", parens![src.as_ref().unwrap().to_owned()]]),
ModuleContextMode::TargetAny =>
item(seq![src.as_ref().unwrap().to_owned(), ".clone()"]),
}
@ -141,7 +141,7 @@ fn simple_pattern_unparser(
SimplePattern::Embedded { .. } => {
match ctxt.m.mode {
ModuleContextMode::TargetIOValue =>
item(seq!["preserves::value::Value::Embedded(", src.as_ref().unwrap().to_owned(), ".as_preserves()).wrap()"]),
item(seq!["preserves::value::Value::Embedded(preserves::value::IOValue::from(&**", src.as_ref().unwrap().to_owned(), ")).wrap()"]),
ModuleContextMode::TargetAny =>
item(seq!["preserves::value::Value::Embedded(", src.as_ref().unwrap().to_owned(), ".clone()).wrap()"]),
}

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,7 @@ mod tests {
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)?;
let parsed = Schema::try_from(schema.clone()).expect("successful parse");
let parsed = Schema::try_from(&schema).expect("successful parse");
assert_eq!(schema, IOValue::from(&parsed));
Ok(())
}

View File

@ -1,7 +1,42 @@
use std::convert::From;
pub use lazy_static::lazy_static;
use preserves::value::ArcValue;
use preserves::value::Domain;
use preserves::value::Embeddable;
use preserves::value::IOResult;
use preserves::value::IOValue;
use preserves::value::NestedValue;
use preserves::value::Value;
use std::convert::From;
use std::convert::TryFrom;
use std::sync::Arc;
pub fn decode_lit<D: Embeddable, N: NestedValue<D>>(bs: &[u8]) -> IOResult<N> {
preserves::value::packed::from_bytes(bs).unwrap().copy_via(
&mut |_| Err(std::io::Error::new(std::io::ErrorKind::Unsupported,
"Embedded values not supported in schema literals")))
}
pub fn decode_embedded<D: Domain>(
v: &IOValue,
) -> Result<ArcValue<Arc<D>>, ParseError>
where
for<'a> D: TryFrom<&'a IOValue, Error = ParseError>
{
v.copy_via(&mut |d| Ok(Value::Embedded(Arc::new(D::try_from(d)?))))
}
pub fn encode_embedded<D: Domain>(
v: &ArcValue<Arc<D>>,
) -> IOValue
where
for<'a> IOValue: From<&'a D>
{
v.copy_via::<_, _, _, std::convert::Infallible>(
&mut |d| Ok(Value::Embedded(IOValue::from(d)))).unwrap()
}
#[derive(Debug)]
pub enum ParseError {
ConformanceError,