cargo fmt

This commit is contained in:
Tony Garnock-Jones 2023-07-21 18:15:30 +02:00
parent 32ee76f7d8
commit 930964ca05
45 changed files with 4369 additions and 2105 deletions

View File

@ -38,7 +38,11 @@ impl Env {
load_schema_or_bundle(&mut self.0, filename) load_schema_or_bundle(&mut self.0, filename)
} }
pub fn lookup_definition(&self, module: &Vec<String>, name: &str) -> Option<&Definition<IOValue>> { pub fn lookup_definition(
&self,
module: &Vec<String>,
name: &str,
) -> Option<&Definition<IOValue>> {
self.0.get(module).and_then(|s| s.definitions.0.get(name)) self.0.get(module).and_then(|s| s.definitions.0.get(name))
} }

View File

@ -14,8 +14,8 @@ pub use context::Env;
pub use error::CompilationError; pub use error::CompilationError;
pub use parse::parse_selector;
pub use parse::parse_predicate; pub use parse::parse_predicate;
pub use parse::parse_selector;
pub use schemas::path::Predicate; pub use schemas::path::Predicate;
pub use schemas::path::Selector; pub use schemas::path::Selector;

View File

@ -1,7 +1,7 @@
use crate::CompilationError;
use crate::context::Env; use crate::context::Env;
use crate::schemas::path; use crate::schemas::path;
use crate::step::Node; use crate::step::Node;
use crate::CompilationError;
use preserves::value::BinarySource; use preserves::value::BinarySource;
use preserves::value::BytesBinarySource; use preserves::value::BytesBinarySource;
@ -49,7 +49,10 @@ pub fn parse_predicate(env: &Env, tokens: &[IOValue]) -> Result<path::Predicate,
match binop { match binop {
None => parse_non_binop(env, &pieces[0]), None => parse_non_binop(env, &pieces[0]),
Some(o) => { Some(o) => {
let preds = pieces.into_iter().map(|ts| parse_non_binop(env, &ts)).collect::<Result<_,_>>()?; let preds = pieces
.into_iter()
.map(|ts| parse_non_binop(env, &ts))
.collect::<Result<_, _>>()?;
Ok(match o { Ok(match o {
Binop::Union => path::Predicate::Or { preds }, Binop::Union => path::Predicate::Or { preds },
Binop::Intersection => path::Predicate::And { preds }, Binop::Intersection => path::Predicate::And { preds },
@ -63,24 +66,42 @@ fn parse_non_binop(env: &Env, tokens: &[IOValue]) -> Result<path::Predicate, Com
let t = tokens[0].value(); let t = tokens[0].value();
if let Some("!") = t.as_symbol().map(|s| s.as_str()) { if let Some("!") = t.as_symbol().map(|s| s.as_str()) {
return Ok(path::Predicate::Not { pred: Box::new(parse_non_binop(env, &tokens[1..])?) }); return Ok(path::Predicate::Not {
pred: Box::new(parse_non_binop(env, &tokens[1..])?),
});
} }
} }
Ok(path::Predicate::Selector(Box::new(parse_selector(env, tokens)?))) Ok(path::Predicate::Selector(Box::new(parse_selector(
env, tokens,
)?)))
} }
fn parse_schema_definition_name(env: &Env, token: &IOValue) -> Result<(Vec<String>, String), CompilationError> { fn parse_schema_definition_name(
let defpath = token.value().to_symbol().map_err(|_| CompilationError::InvalidStep)?; env: &Env,
token: &IOValue,
) -> Result<(Vec<String>, String), CompilationError> {
let defpath = token
.value()
.to_symbol()
.map_err(|_| CompilationError::InvalidStep)?;
let mut module: Vec<String> = defpath.split('.').map(|s| s.to_string()).collect(); let mut module: Vec<String> = defpath.split('.').map(|s| s.to_string()).collect();
let name = module.pop().expect("at least one element in the Schema name"); let name = module
.pop()
.expect("at least one element in the Schema name");
match env.lookup_definition(&module, &name) { match env.lookup_definition(&module, &name) {
Some(_) => Ok((module, name)), Some(_) => Ok((module, name)),
None => Err(CompilationError::UndefinedSchemaDefinitionName(format!("{:?}", token))), None => Err(CompilationError::UndefinedSchemaDefinitionName(format!(
"{:?}",
token
))),
} }
} }
fn parse_step<'a>(env: &Env, tokens: &'a [IOValue]) -> Result<Option<(path::Step, &'a [IOValue])>, CompilationError> { fn parse_step<'a>(
env: &Env,
tokens: &'a [IOValue],
) -> Result<Option<(path::Step, &'a [IOValue])>, CompilationError> {
if tokens.is_empty() { if tokens.is_empty() {
return Ok(None); return Ok(None);
} }
@ -88,9 +109,15 @@ fn parse_step<'a>(env: &Env, tokens: &'a [IOValue]) -> Result<Option<(path::Step
let remainder = &tokens[1..]; let remainder = &tokens[1..];
if tokens[0].value().is_sequence() { if tokens[0].value().is_sequence() {
return Ok(Some((path::Step::Filter(Box::new(path::Filter::Test { return Ok(Some((
pred: Box::new(parse_predicate(env, tokens[0].value().as_sequence().unwrap())?), path::Step::Filter(Box::new(path::Filter::Test {
})), remainder))); pred: Box::new(parse_predicate(
env,
tokens[0].value().as_sequence().unwrap(),
)?),
})),
remainder,
)));
} }
match tokens[0].value().as_record(None) { match tokens[0].value().as_record(None) {
@ -98,42 +125,77 @@ fn parse_step<'a>(env: &Env, tokens: &'a [IOValue]) -> Result<Option<(path::Step
Some(r) => match r.label().value().as_symbol() { Some(r) => match r.label().value().as_symbol() {
None => return Err(CompilationError::InvalidStep), None => return Err(CompilationError::InvalidStep),
Some(t) => match t.as_str() { Some(t) => match t.as_str() {
"count" => return Ok(Some(( "count" => {
path::Step::Function(Box::new(path::Function { return Ok(Some((
selector: parse_selector(env, r.fields())?, path::Step::Function(Box::new(path::Function {
})), selector: parse_selector(env, r.fields())?,
remainder })),
))), remainder,
)))
}
_ => return Err(CompilationError::InvalidStep), _ => return Err(CompilationError::InvalidStep),
} },
} },
} }
match tokens[0].value().as_symbol() { match tokens[0].value().as_symbol() {
None => return Err(CompilationError::InvalidStep), None => return Err(CompilationError::InvalidStep),
Some(t) => match t.as_str() { Some(t) => match t.as_str() {
"/" => Ok(Some((path::Step::Axis(Box::new(path::Axis::Values)), remainder))), "/" => Ok(Some((
"//" => Ok(Some((path::Step::Axis(Box::new(path::Axis::Descendants)), remainder))), path::Step::Axis(Box::new(path::Axis::Values)),
remainder,
))),
"//" => Ok(Some((
path::Step::Axis(Box::new(path::Axis::Descendants)),
remainder,
))),
"." => { "." => {
let (key, remainder) = pop_step_arg(remainder)?; let (key, remainder) = pop_step_arg(remainder)?;
Ok(Some((path::Step::Axis(Box::new(path::Axis::At { key })), remainder))) Ok(Some((
path::Step::Axis(Box::new(path::Axis::At { key })),
remainder,
)))
} }
".^" => Ok(Some((path::Step::Axis(Box::new(path::Axis::Label)), remainder))), ".^" => Ok(Some((
".keys" => Ok(Some((path::Step::Axis(Box::new(path::Axis::Keys)), remainder))), path::Step::Axis(Box::new(path::Axis::Label)),
".length" => Ok(Some((path::Step::Axis(Box::new(path::Axis::Length)), remainder))), remainder,
".annotations" => Ok(Some((path::Step::Axis(Box::new(path::Axis::Annotations)), remainder))), ))),
".embedded" => Ok(Some((path::Step::Axis(Box::new(path::Axis::Embedded)), remainder))), ".keys" => Ok(Some((
path::Step::Axis(Box::new(path::Axis::Keys)),
remainder,
))),
".length" => Ok(Some((
path::Step::Axis(Box::new(path::Axis::Length)),
remainder,
))),
".annotations" => Ok(Some((
path::Step::Axis(Box::new(path::Axis::Annotations)),
remainder,
))),
".embedded" => Ok(Some((
path::Step::Axis(Box::new(path::Axis::Embedded)),
remainder,
))),
"%" => { "%" => {
let (defpath, remainder) = pop_step_arg(remainder)?; let (defpath, remainder) = pop_step_arg(remainder)?;
let (module, name) = parse_schema_definition_name(env, &defpath)?; let (module, name) = parse_schema_definition_name(env, &defpath)?;
Ok(Some((path::Step::Axis(Box::new(path::Axis::Parse { module, name })), remainder))) Ok(Some((
path::Step::Axis(Box::new(path::Axis::Parse { module, name })),
remainder,
)))
} }
"%-" => { "%-" => {
let (defpath, remainder) = pop_step_arg(remainder)?; let (defpath, remainder) = pop_step_arg(remainder)?;
let (module, name) = parse_schema_definition_name(env, &defpath)?; let (module, name) = parse_schema_definition_name(env, &defpath)?;
Ok(Some((path::Step::Axis(Box::new(path::Axis::Unparse { module, name })), remainder))) Ok(Some((
path::Step::Axis(Box::new(path::Axis::Unparse { module, name })),
remainder,
)))
} }
"*" => Ok(Some((path::Step::Filter(Box::new(path::Filter::Nop)), remainder))), "*" => Ok(Some((
path::Step::Filter(Box::new(path::Filter::Nop)),
remainder,
))),
"eq" | "=" => parse_comparison(remainder, path::Comparison::Eq), "eq" | "=" => parse_comparison(remainder, path::Comparison::Eq),
"ne" | "!=" => parse_comparison(remainder, path::Comparison::Ne), "ne" | "!=" => parse_comparison(remainder, path::Comparison::Ne),
"lt" => parse_comparison(remainder, path::Comparison::Lt), "lt" => parse_comparison(remainder, path::Comparison::Lt),
@ -142,49 +204,81 @@ fn parse_step<'a>(env: &Env, tokens: &'a [IOValue]) -> Result<Option<(path::Step
"ge" => parse_comparison(remainder, path::Comparison::Ge), "ge" => parse_comparison(remainder, path::Comparison::Ge),
"re" | "=r" => { "re" | "=r" => {
let (regex_val, remainder) = pop_step_arg(remainder)?; let (regex_val, remainder) = pop_step_arg(remainder)?;
let regex = regex_val.value().to_string().map_err(|_| CompilationError::InvalidStep)?.clone(); let regex = regex_val
.value()
.to_string()
.map_err(|_| CompilationError::InvalidStep)?
.clone();
let _ = regex::Regex::new(&regex)?; let _ = regex::Regex::new(&regex)?;
Ok(Some((path::Step::Filter(Box::new(path::Filter::Regex { regex })), remainder))) Ok(Some((
path::Step::Filter(Box::new(path::Filter::Regex { regex })),
remainder,
)))
} }
"^" => { "^" => {
let (literal, remainder) = pop_step_arg(remainder)?; let (literal, remainder) = pop_step_arg(remainder)?;
Ok(Some((path::Step::Filter(Box::new(path::Filter::Test { Ok(Some((
pred: Box::new(path::Predicate::Selector(Box::new(path::Selector(vec![ path::Step::Filter(Box::new(path::Filter::Test {
path::Step::Axis(Box::new(path::Axis::Label)), pred: Box::new(path::Predicate::Selector(Box::new(path::Selector(vec![
path::Step::Filter(Box::new(path::Filter::Compare { path::Step::Axis(Box::new(path::Axis::Label)),
op: Box::new(path::Comparison::Eq), path::Step::Filter(Box::new(path::Filter::Compare {
literal, op: Box::new(path::Comparison::Eq),
})), literal,
])))), })),
})), remainder))) ])))),
})),
remainder,
)))
} }
"~real" => Ok(Some((path::Step::Filter(Box::new(path::Filter::Real)), remainder))), "~real" => Ok(Some((
"~int" => Ok(Some((path::Step::Filter(Box::new(path::Filter::Int)), remainder))), path::Step::Filter(Box::new(path::Filter::Real)),
remainder,
))),
"~int" => Ok(Some((
path::Step::Filter(Box::new(path::Filter::Int)),
remainder,
))),
"bool" => Ok(Some((path::Step::from(path::ValueKind::Boolean), remainder))), "bool" => Ok(Some((
path::Step::from(path::ValueKind::Boolean),
remainder,
))),
"float" => Ok(Some((path::Step::from(path::ValueKind::Float), remainder))), "float" => Ok(Some((path::Step::from(path::ValueKind::Float), remainder))),
"double" => Ok(Some((path::Step::from(path::ValueKind::Double), remainder))), "double" => Ok(Some((path::Step::from(path::ValueKind::Double), remainder))),
"int" => Ok(Some((path::Step::from(path::ValueKind::SignedInteger), remainder))), "int" => Ok(Some((
path::Step::from(path::ValueKind::SignedInteger),
remainder,
))),
"string" => Ok(Some((path::Step::from(path::ValueKind::String), remainder))), "string" => Ok(Some((path::Step::from(path::ValueKind::String), remainder))),
"bytes" => Ok(Some((path::Step::from(path::ValueKind::ByteString), remainder))), "bytes" => Ok(Some((
path::Step::from(path::ValueKind::ByteString),
remainder,
))),
"symbol" => Ok(Some((path::Step::from(path::ValueKind::Symbol), remainder))), "symbol" => Ok(Some((path::Step::from(path::ValueKind::Symbol), remainder))),
"rec" => Ok(Some((path::Step::from(path::ValueKind::Record), remainder))), "rec" => Ok(Some((path::Step::from(path::ValueKind::Record), remainder))),
"seq" => Ok(Some((path::Step::from(path::ValueKind::Sequence), remainder))), "seq" => Ok(Some((
path::Step::from(path::ValueKind::Sequence),
remainder,
))),
"set" => Ok(Some((path::Step::from(path::ValueKind::Set), remainder))), "set" => Ok(Some((path::Step::from(path::ValueKind::Set), remainder))),
"dict" => Ok(Some((path::Step::from(path::ValueKind::Dictionary), remainder))), "dict" => Ok(Some((
"embedded" => Ok(Some((path::Step::from(path::ValueKind::Embedded), remainder))), path::Step::from(path::ValueKind::Dictionary),
remainder,
))),
"embedded" => Ok(Some((
path::Step::from(path::ValueKind::Embedded),
remainder,
))),
_ => Err(CompilationError::InvalidStep), _ => Err(CompilationError::InvalidStep),
} },
} }
} }
impl From<path::ValueKind> for path::Step { impl From<path::ValueKind> for path::Step {
fn from(k: path::ValueKind) -> Self { fn from(k: path::ValueKind) -> Self {
path::Step::Filter(Box::new(path::Filter::Kind { path::Step::Filter(Box::new(path::Filter::Kind { kind: Box::new(k) }))
kind: Box::new(k),
}))
} }
} }
@ -200,18 +294,24 @@ fn parse_comparison(
op: path::Comparison, op: path::Comparison,
) -> Result<Option<(path::Step, &[IOValue])>, CompilationError> { ) -> Result<Option<(path::Step, &[IOValue])>, CompilationError> {
let (literal, remainder) = pop_step_arg(tokens)?; let (literal, remainder) = pop_step_arg(tokens)?;
Ok(Some((path::Step::Filter(Box::new(path::Filter::Compare { Ok(Some((
op: Box::new(op), path::Step::Filter(Box::new(path::Filter::Compare {
literal, op: Box::new(op),
})), remainder))) literal,
})),
remainder,
)))
} }
impl path::Selector { impl path::Selector {
pub fn from_str(env: &Env, s: &str) -> Result<Self, CompilationError> { pub fn from_str(env: &Env, s: &str) -> Result<Self, CompilationError> {
parse_selector(env, &(BytesBinarySource::new(s.as_bytes()) parse_selector(
.text_iovalues() env,
.configured(false) &(BytesBinarySource::new(s.as_bytes())
.collect::<Result<Vec<_>, _>>()?)) .text_iovalues()
.configured(false)
.collect::<Result<Vec<_>, _>>()?),
)
} }
} }

View File

@ -1,9 +1,9 @@
use crate::CompilationError;
use crate::context::Context; use crate::context::Context;
use crate::schemas::path; use crate::schemas::path;
use crate::step::BoolCollector; use crate::step::BoolCollector;
use crate::step::Node; use crate::step::Node;
use crate::step::StepMaker; use crate::step::StepMaker;
use crate::CompilationError;
use preserves::value::IOValue; use preserves::value::IOValue;
@ -22,14 +22,18 @@ pub enum CompiledPredicate {
impl path::Predicate { impl path::Predicate {
pub fn compile(&self) -> Result<CompiledPredicate, CompilationError> { pub fn compile(&self) -> Result<CompiledPredicate, CompilationError> {
match self { match self {
path::Predicate::Selector(b) => path::Predicate::Selector(b) => Ok(CompiledPredicate::Selector(
Ok(CompiledPredicate::Selector((&**b).connect(BoolCollector::new())?)), (&**b).connect(BoolCollector::new())?,
path::Predicate::Not { pred } => )),
Ok(CompiledPredicate::Not(Box::new((&**pred).compile()?))), path::Predicate::Not { pred } => {
path::Predicate::Or { preds } => Ok(CompiledPredicate::Not(Box::new((&**pred).compile()?)))
Ok(CompiledPredicate::Or(preds.iter().map(Self::compile).collect::<Result<_,_>>()?)), }
path::Predicate::And { preds } => path::Predicate::Or { preds } => Ok(CompiledPredicate::Or(
Ok(CompiledPredicate::And(preds.iter().map(Self::compile).collect::<Result<_,_>>()?)), preds.iter().map(Self::compile).collect::<Result<_, _>>()?,
)),
path::Predicate::And { preds } => Ok(CompiledPredicate::And(
preds.iter().map(Self::compile).collect::<Result<_, _>>()?,
)),
} }
} }
@ -50,7 +54,7 @@ impl Predicate for CompiledPredicate {
} }
} }
return false; return false;
}, }
CompiledPredicate::And(ps) => { CompiledPredicate::And(ps) => {
for p in ps.iter_mut() { for p in ps.iter_mut() {
if !p.test(ctxt, value) { if !p.test(ctxt, value) {
@ -58,8 +62,7 @@ impl Predicate for CompiledPredicate {
} }
} }
return true; return true;
}, }
} }
} }
} }

View File

@ -1,15 +1,15 @@
// Selectors operate on IOValues because the AST includes keys of IOValue type. // Selectors operate on IOValues because the AST includes keys of IOValue type.
// If we could make Schemas produce generics... // If we could make Schemas produce generics...
use crate::CompilationError;
use crate::context::Context; use crate::context::Context;
use crate::predicate::CompiledPredicate; use crate::predicate::CompiledPredicate;
use crate::predicate::Predicate; use crate::predicate::Predicate;
use crate::schemas::path; use crate::schemas::path;
use crate::CompilationError;
use num::bigint::BigInt; use num::bigint::BigInt;
use num::traits::cast::ToPrimitive;
use num::traits::cast::FromPrimitive; use num::traits::cast::FromPrimitive;
use num::traits::cast::ToPrimitive;
use preserves::value::AtomClass; use preserves::value::AtomClass;
use preserves::value::CompoundClass; use preserves::value::CompoundClass;
@ -161,7 +161,10 @@ impl StepMaker for path::Step {
impl StepMaker for path::Axis { impl StepMaker for path::Axis {
fn connect(&self, step: Node) -> Result<Node, CompilationError> { fn connect(&self, step: Node) -> Result<Node, CompilationError> {
Ok(Node::new(AxisStep { step, axis: self.clone() })) Ok(Node::new(AxisStep {
step,
axis: self.clone(),
}))
} }
} }
@ -175,64 +178,81 @@ fn descendants(ctxt: &mut Context, step: &mut Node, v: &IOValue) {
impl Step for AxisStep { impl Step for AxisStep {
fn accept(&mut self, ctxt: &mut Context, value: &IOValue) { fn accept(&mut self, ctxt: &mut Context, value: &IOValue) {
ctxt.with_path_step(value, |ctxt| match &self.axis { ctxt.with_path_step(value, |ctxt| match &self.axis {
path::Axis::Values => path::Axis::Values => {
for c in value.value().children() { for c in value.value().children() {
self.step.accept(ctxt, &c) self.step.accept(ctxt, &c)
}, }
path::Axis::Descendants => }
descendants(ctxt, &mut self.step, value), path::Axis::Descendants => descendants(ctxt, &mut self.step, value),
path::Axis::At { key } => match value.value() { path::Axis::At { key } => match value.value() {
Value::String(s) | Value::Symbol(s) => Value::String(s) | Value::Symbol(s) => step_index(
step_index(ctxt, s.chars(), &key, |c| IOValue::new(String::from(c)), &mut self.step), ctxt,
Value::Record(r) => s.chars(),
step_index(ctxt, r.fields().iter(), &key, |v| v.clone(), &mut self.step), &key,
Value::Sequence(vs) => |c| IOValue::new(String::from(c)),
step_index(ctxt, vs.iter(), &key, |v| v.clone(), &mut self.step), &mut self.step,
Value::Dictionary(d) => ),
Value::Record(r) => {
step_index(ctxt, r.fields().iter(), &key, |v| v.clone(), &mut self.step)
}
Value::Sequence(vs) => {
step_index(ctxt, vs.iter(), &key, |v| v.clone(), &mut self.step)
}
Value::Dictionary(d) => {
if let Some(v) = d.get(&key) { if let Some(v) = d.get(&key) {
self.step.accept(ctxt, v) self.step.accept(ctxt, v)
}, }
_ => }
(), _ => (),
},
path::Axis::Label => if let Some(r) = value.value().as_record(None) {
self.step.accept(ctxt, r.label())
}, },
path::Axis::Label => {
if let Some(r) = value.value().as_record(None) {
self.step.accept(ctxt, r.label())
}
}
path::Axis::Keys => match value.value() { path::Axis::Keys => match value.value() {
Value::String(s) | Value::Symbol(s) => Value::String(s) | Value::Symbol(s) => step_keys(ctxt, s.len(), &mut self.step),
step_keys(ctxt, s.len(), &mut self.step),
Value::ByteString(bs) => step_keys(ctxt, bs.len(), &mut self.step), Value::ByteString(bs) => step_keys(ctxt, bs.len(), &mut self.step),
Value::Record(r) => step_keys(ctxt, r.arity(), &mut self.step), Value::Record(r) => step_keys(ctxt, r.arity(), &mut self.step),
Value::Sequence(vs) => step_keys(ctxt, vs.len(), &mut self.step), Value::Sequence(vs) => step_keys(ctxt, vs.len(), &mut self.step),
Value::Dictionary(d) => Value::Dictionary(d) => {
for k in d.keys() { for k in d.keys() {
self.step.accept(ctxt, k) self.step.accept(ctxt, k)
}, }
}
_ => (), _ => (),
}, },
path::Axis::Length => match value.value() { path::Axis::Length => match value.value() {
Value::String(s) | Value::Symbol(s) => Value::String(s) | Value::Symbol(s) => {
self.step.accept(ctxt, &IOValue::new(s.len())), self.step.accept(ctxt, &IOValue::new(s.len()))
}
Value::ByteString(bs) => self.step.accept(ctxt, &IOValue::new(bs.len())), Value::ByteString(bs) => self.step.accept(ctxt, &IOValue::new(bs.len())),
Value::Record(r) => self.step.accept(ctxt, &IOValue::new(r.arity())), Value::Record(r) => self.step.accept(ctxt, &IOValue::new(r.arity())),
Value::Sequence(vs) => self.step.accept(ctxt, &IOValue::new(vs.len())), Value::Sequence(vs) => self.step.accept(ctxt, &IOValue::new(vs.len())),
Value::Dictionary(d) => self.step.accept(ctxt, &IOValue::new(d.len())), Value::Dictionary(d) => self.step.accept(ctxt, &IOValue::new(d.len())),
_ => self.step.accept(ctxt, &IOValue::new(0)), _ => self.step.accept(ctxt, &IOValue::new(0)),
}, },
path::Axis::Annotations => path::Axis::Annotations => {
for c in value.annotations().slice() { for c in value.annotations().slice() {
self.step.accept(ctxt, &c) self.step.accept(ctxt, &c)
}, }
path::Axis::Embedded => if let Some(d) = value.value().as_embedded() { }
self.step.accept(ctxt, d) path::Axis::Embedded => {
}, if let Some(d) = value.value().as_embedded() {
self.step.accept(ctxt, d)
}
}
path::Axis::Parse { module, name } => { path::Axis::Parse { module, name } => {
if let Some(p) = interpret::Context::new(&ctxt.env.0).dynamic_parse(module, name, value) { if let Some(p) =
interpret::Context::new(&ctxt.env.0).dynamic_parse(module, name, value)
{
self.step.accept(ctxt, &p) self.step.accept(ctxt, &p)
} }
} }
path::Axis::Unparse { module, name } => { path::Axis::Unparse { module, name } => {
if let Some(p) = interpret::Context::new(&ctxt.env.0).dynamic_unparse(module, name, value) { if let Some(p) =
interpret::Context::new(&ctxt.env.0).dynamic_unparse(module, name, value)
{
self.step.accept(ctxt, &p) self.step.accept(ctxt, &p)
} }
} }
@ -258,7 +278,7 @@ fn step_index<T, Ts: Iterator<Item = T>, F: FnOnce(T) -> IOValue>(
} }
fn step_keys(ctxt: &mut Context, count: usize, step: &mut Node) { fn step_keys(ctxt: &mut Context, count: usize, step: &mut Node) {
for i in 0 .. count { for i in 0..count {
step.accept(ctxt, &IOValue::new(i)) step.accept(ctxt, &IOValue::new(i))
} }
} }
@ -272,8 +292,14 @@ impl StepMaker for path::Filter {
literal: literal.clone(), literal: literal.clone(),
step, step,
})), })),
path::Filter::Regex { regex } => Ok(Node::new(RegexStep { regex: regex::Regex::new(regex)?, step })), path::Filter::Regex { regex } => Ok(Node::new(RegexStep {
path::Filter::Test { pred } => Ok(Node::new(TestStep { pred: (&**pred).compile()?, step })), regex: regex::Regex::new(regex)?,
step,
})),
path::Filter::Test { pred } => Ok(Node::new(TestStep {
pred: (&**pred).compile()?,
step,
})),
path::Filter::Real => Ok(Node::new(RealStep { step })), path::Filter::Real => Ok(Node::new(RealStep { step })),
path::Filter::Int => Ok(Node::new(IntStep { step })), path::Filter::Int => Ok(Node::new(IntStep { step })),
path::Filter::Kind { kind } => Ok(Node::new(KindStep { path::Filter::Kind { kind } => Ok(Node::new(KindStep {
@ -317,10 +343,12 @@ impl Step for CompareStep {
impl Step for RegexStep { impl Step for RegexStep {
fn accept(&mut self, ctxt: &mut Context, value: &IOValue) { fn accept(&mut self, ctxt: &mut Context, value: &IOValue) {
match value.value() { match value.value() {
Value::String(s) | Value::Symbol(s) => Value::String(s) | Value::Symbol(s) => {
if self.regex.is_match(s) { self.step.accept(ctxt, value) }, if self.regex.is_match(s) {
_ => self.step.accept(ctxt, value)
(), }
}
_ => (),
} }
} }
@ -340,9 +368,11 @@ impl Step for TestStep {
impl Step for RealStep { impl Step for RealStep {
fn accept(&mut self, ctxt: &mut Context, value: &IOValue) { fn accept(&mut self, ctxt: &mut Context, value: &IOValue) {
match value.value() { match value.value() {
Value::SignedInteger(i) => if let Some(r) = BigInt::from(i).to_f64() { Value::SignedInteger(i) => {
self.step.accept(ctxt, &IOValue::new(r)) if let Some(r) = BigInt::from(i).to_f64() {
}, self.step.accept(ctxt, &IOValue::new(r))
}
}
Value::Float(f) => self.step.accept(ctxt, &IOValue::new(f32::from(*f) as f64)), Value::Float(f) => self.step.accept(ctxt, &IOValue::new(f32::from(*f) as f64)),
Value::Double(_) => self.step.accept(ctxt, value), Value::Double(_) => self.step.accept(ctxt, value),
_ => (), _ => (),
@ -356,12 +386,16 @@ impl Step for IntStep {
fn accept(&mut self, ctxt: &mut Context, value: &IOValue) { fn accept(&mut self, ctxt: &mut Context, value: &IOValue) {
match value.value() { match value.value() {
Value::SignedInteger(_) => self.step.accept(ctxt, value), Value::SignedInteger(_) => self.step.accept(ctxt, value),
Value::Float(f) => if let Some(i) = BigInt::from_f32(f32::from(*f)) { Value::Float(f) => {
self.step.accept(ctxt, &IOValue::new(i)) if let Some(i) = BigInt::from_f32(f32::from(*f)) {
}, self.step.accept(ctxt, &IOValue::new(i))
Value::Double(d) => if let Some(i) = BigInt::from_f64(f64::from(*d)) { }
self.step.accept(ctxt, &IOValue::new(i)) }
}, Value::Double(d) => {
if let Some(i) = BigInt::from_f64(f64::from(*d)) {
self.step.accept(ctxt, &IOValue::new(i))
}
}
_ => (), _ => (),
} }
} }
@ -371,7 +405,9 @@ impl Step for IntStep {
impl VecCollector { impl VecCollector {
fn new() -> Node { fn new() -> Node {
Node::new(VecCollector { accumulator: Vec::new() }) Node::new(VecCollector {
accumulator: Vec::new(),
})
} }
} }
@ -380,8 +416,7 @@ impl Step for VecCollector {
self.accumulator.push(value.clone()) self.accumulator.push(value.clone())
} }
fn finish(&mut self) { fn finish(&mut self) {}
}
fn reset(&mut self) -> Vec<IOValue> { fn reset(&mut self) -> Vec<IOValue> {
std::mem::take(&mut self.accumulator) std::mem::take(&mut self.accumulator)
@ -399,11 +434,14 @@ impl Step for BoolCollector {
self.seen_value = true self.seen_value = true
} }
fn finish(&mut self) { fn finish(&mut self) {}
}
fn reset(&mut self) -> Vec<IOValue> { fn reset(&mut self) -> Vec<IOValue> {
let result = if self.seen_value { vec![IOValue::new(true)] } else { vec![] }; let result = if self.seen_value {
vec![IOValue::new(true)]
} else {
vec![]
};
self.seen_value = false; self.seen_value = false;
result result
} }
@ -424,7 +462,11 @@ impl path::Selector {
self.connect(VecCollector::new()) self.connect(VecCollector::new())
} }
pub fn exec(&self, ctxt: &mut Context, value: &IOValue) -> Result<Vec<IOValue>, CompilationError> { pub fn exec(
&self,
ctxt: &mut Context,
value: &IOValue,
) -> Result<Vec<IOValue>, CompilationError> {
Ok(self.compile()?.exec(ctxt, value)) Ok(self.compile()?.exec(ctxt, value))
} }
} }
@ -432,7 +474,10 @@ impl path::Selector {
impl StepMaker for path::Function { impl StepMaker for path::Function {
fn connect(&self, step: Node) -> Result<Node, CompilationError> { fn connect(&self, step: Node) -> Result<Node, CompilationError> {
// For now, there's just one function: `count`. // For now, there's just one function: `count`.
Ok(Node::new(CountStep { step, counter: self.selector.connect(CountCollector::new())? })) Ok(Node::new(CountStep {
step,
counter: self.selector.connect(CountCollector::new())?,
}))
} }
} }
@ -447,8 +492,7 @@ impl Step for CountCollector {
self.count += 1 self.count += 1
} }
fn finish(&mut self) { fn finish(&mut self) {}
}
fn reset(&mut self) -> Vec<IOValue> { fn reset(&mut self) -> Vec<IOValue> {
let result = vec![IOValue::new(self.count)]; let result = vec![IOValue::new(self.count)];

View File

@ -3,7 +3,7 @@ use std::io::ErrorKind;
use std::path::PathBuf; use std::path::PathBuf;
use structopt::StructOpt; use structopt::StructOpt;
use preserves_schema::compiler::{ExternalModule, CompilerConfig, compile, expand_inputs}; use preserves_schema::compiler::{compile, expand_inputs, CompilerConfig, ExternalModule};
#[derive(Clone, StructOpt, Debug)] #[derive(Clone, StructOpt, Debug)]
struct CommandLine { struct CommandLine {
@ -35,8 +35,10 @@ fn main() -> Result<(), Error> {
let (modulepath_str, target) = { let (modulepath_str, target) = {
let pieces: Vec<&str> = alias.split('=').collect(); let pieces: Vec<&str> = alias.split('=').collect();
if pieces.len() != 2 { if pieces.len() != 2 {
return Err(Error::new(ErrorKind::InvalidData, return Err(Error::new(
format!("Invalid module alias: {:?}", alias))); ErrorKind::InvalidData,
format!("Invalid module alias: {:?}", alias),
));
} }
(pieces[0], pieces[1]) (pieces[0], pieces[1])
}; };
@ -49,6 +51,7 @@ fn main() -> Result<(), Error> {
config.rustfmt_skip = args.rustfmt_skip; config.rustfmt_skip = args.rustfmt_skip;
config.load_schemas_and_bundles( config.load_schemas_and_bundles(
&expand_inputs(&args.input_glob)?, &expand_inputs(&args.input_glob)?,
&expand_inputs(&args.xref)?)?; &expand_inputs(&args.xref)?,
)?;
compile(&config) compile(&config)
} }

View File

@ -1,8 +1,8 @@
use crate::*;
use crate::syntax::block::Item;
use crate::syntax::block::escape_string;
use crate::syntax::block::constructors::*;
use crate::gen::schema::*; use crate::gen::schema::*;
use crate::syntax::block::constructors::*;
use crate::syntax::block::escape_string;
use crate::syntax::block::Item;
use crate::*;
use convert_case::{Case, Casing}; use convert_case::{Case, Casing};
@ -13,10 +13,10 @@ use preserves::value::Map;
use preserves::value::NestedValue; use preserves::value::NestedValue;
use preserves::value::Value; use preserves::value::Value;
use super::CompilerConfig;
use super::names; use super::names;
use super::types; use super::types;
use super::types::Purpose; use super::types::Purpose;
use super::CompilerConfig;
pub struct BundleContext<'b> { pub struct BundleContext<'b> {
pub config: &'b CompilerConfig, pub config: &'b CompilerConfig,
@ -69,9 +69,7 @@ lazy_static! {
} }
impl<'b> BundleContext<'b> { impl<'b> BundleContext<'b> {
pub fn new( pub fn new(config: &'b CompilerConfig) -> Self {
config: &'b CompilerConfig,
) -> Self {
BundleContext { BundleContext {
config, config,
types: config.build_type_cache(), types: config.build_type_cache(),
@ -84,13 +82,18 @@ impl<'b> BundleContext<'b> {
} }
pub fn lookup_definition(&self, r: &Ref) -> Option<(&Definition, Purpose)> { pub fn lookup_definition(&self, r: &Ref) -> Option<(&Definition, Purpose)> {
self.config.bundle.get(&r.module.0).and_then( self.config
|s| s.0.definitions.0.get(&r.name).map(|d| (d, s.1))) .bundle
.get(&r.module.0)
.and_then(|s| s.0.definitions.0.get(&r.name).map(|d| (d, s.1)))
} }
pub fn type_for_name(&self, r: &Ref) -> Option<&types::TDefinition> { pub fn type_for_name(&self, r: &Ref) -> Option<&types::TDefinition> {
if r.module.0.is_empty() { if r.module.0.is_empty() {
panic!("BundleContext::type_for_name with module-relative ref {:?}", r); panic!(
"BundleContext::type_for_name with module-relative ref {:?}",
r
);
} }
let result = self.types.get(r); let result = self.types.get(r);
if result.is_none() && !self.config.external_modules.contains_key(&r.module.0) { if result.is_none() && !self.config.external_modules.contains_key(&r.module.0) {
@ -103,15 +106,29 @@ impl<'b> BundleContext<'b> {
let prefix = format!("LIT_{}", self.literals.len()); let prefix = format!("LIT_{}", self.literals.len());
let next_id = match v.value() { let next_id = match v.value() {
Value::Boolean(b) => prefix + "_" + &b.to_string(), Value::Boolean(b) => prefix + "_" + &b.to_string(),
Value::Symbol(s) => if ID_RE.is_match(&s) { prefix + "_" + s } else { prefix }, Value::Symbol(s) => {
Value::String(s) => if ID_RE.is_match(&s) { prefix + "_" + s } else { prefix }, if ID_RE.is_match(&s) {
prefix + "_" + s
} else {
prefix
}
}
Value::String(s) => {
if ID_RE.is_match(&s) {
prefix + "_" + s
} else {
prefix
}
}
Value::SignedInteger(n) => prefix + "_" + &n.to_string(), Value::SignedInteger(n) => prefix + "_" + &n.to_string(),
_ => prefix _ => prefix,
}; };
let next_id = next_id.to_case(Case::UpperSnake); let next_id = next_id.to_case(Case::UpperSnake);
format!("&<_L as Into<&'a {}>>::into(_ctxt).{}", format!(
self.language_type(), "&<_L as Into<&'a {}>>::into(_ctxt).{}",
self.literals.entry(v.clone()).or_insert(next_id)) self.language_type(),
self.literals.entry(v.clone()).or_insert(next_id)
)
} }
pub fn generate_module<F: FnOnce(&mut ModuleContext)>( pub fn generate_module<F: FnOnce(&mut ModuleContext)>(
@ -132,9 +149,11 @@ impl<'b> BundleContext<'b> {
} }
pub fn language_type_base(&self) -> String { pub fn language_type_base(&self) -> String {
format!("{}::{}", format!(
self.config.fully_qualified_module_prefix.clone(), "{}::{}",
self.language_struct_name()) self.config.fully_qualified_module_prefix.clone(),
self.language_struct_name()
)
} }
pub fn language_type(&self) -> String { pub fn language_type(&self) -> String {
@ -175,38 +194,56 @@ impl<'m, 'b> ModuleContext<'m, 'b> {
self.typedefs.push(i) self.typedefs.push(i)
} }
pub fn define_function<F: FnOnce(FunctionContext) -> Item>(&mut self, error_context: &str, f: F) { pub fn define_function<F: FnOnce(FunctionContext) -> Item>(
&mut self,
error_context: &str,
f: F,
) {
let i = f(FunctionContext::new(self, error_context)); let i = f(FunctionContext::new(self, error_context));
self.functiondefs.push(i) self.functiondefs.push(i)
} }
pub fn render_ref(&self, r: &Ref, style: RefRenderStyle) -> Item { pub fn render_ref(&self, r: &Ref, style: RefRenderStyle) -> Item {
let base = match self.bundle.config.external_modules.get(&r.module.0) { let base = match self.bundle.config.external_modules.get(&r.module.0) {
None => None => {
if r.module.0.is_empty() { if r.module.0.is_empty() {
item(names::render_constructor(&r.name)) item(names::render_constructor(&r.name))
} else { } else {
let mut items = Vec::new(); let mut items = Vec::new();
items.push(item(self.bundle.config.fully_qualified_module_prefix.to_owned())); items.push(item(
for p in &r.module.0 { items.push(item(names::render_modname(p))) } self.bundle.config.fully_qualified_module_prefix.to_owned(),
));
for p in &r.module.0 {
items.push(item(names::render_modname(p)))
}
items.push(item(names::render_constructor(&r.name))); items.push(item(names::render_constructor(&r.name)));
item(name(items)) item(name(items))
} }
Some(xm) => }
item(name![xm.rust_namespace.clone(), names::render_constructor(&r.name)]) Some(xm) => item(name![
xm.rust_namespace.clone(),
names::render_constructor(&r.name)
]),
}; };
let q = self.ref_has_embedded(r); let q = self.ref_has_embedded(r);
match style { match style {
RefRenderStyle::Bare => RefRenderStyle::Bare => base,
base, RefRenderStyle::Qualified => {
RefRenderStyle::Qualified => if q {
if q { item(seq![base, anglebrackets![self.any_type()]]) } else { base }, item(seq![base, anglebrackets![self.any_type()]])
} else {
base
}
}
} }
} }
pub fn ref_has_embedded(&self, r: &Ref) -> bool { pub fn ref_has_embedded(&self, r: &Ref) -> bool {
let r = r.qualify(&self.module_path); let r = r.qualify(&self.module_path);
self.bundle.type_for_name(&r).map(|ty| ty.has_embedded(self.bundle)).unwrap_or(false) self.bundle
.type_for_name(&r)
.map(|ty| ty.has_embedded(self.bundle))
.unwrap_or(false)
// ^ TODO: should the "false" be configurable? // ^ TODO: should the "false" be configurable?
} }
@ -215,9 +252,15 @@ impl<'m, 'b> ModuleContext<'m, 'b> {
lts.insert(self.bundle.language_type()); lts.insert(self.bundle.language_type());
item(anglebrackets![ item(anglebrackets![
"'a", "'a",
seq!["_L: Copy", seq![
seq(lts.into_iter().map(|t| item(seq![" + Into<&'a ", t, ">"])).collect())], "_L: Copy",
seq![self.any_type(), ": preserves::value::NestedValue + 'a"]]) seq(lts
.into_iter()
.map(|t| item(seq![" + Into<&'a ", t, ">"]))
.collect())
],
seq![self.any_type(), ": preserves::value::NestedValue + 'a"]
])
} }
pub fn extract(&mut self) -> Vec<Item> { pub fn extract(&mut self) -> Vec<Item> {
@ -243,11 +286,13 @@ impl<'a, 'm, 'b> FunctionContext<'a, 'm, 'b> {
field_name, field_name,
ty, ty,
source_expr: match self.capture_mode { source_expr: match self.capture_mode {
CaptureMode::Definite => CaptureMode::Definite => source_expr,
CaptureMode::Indefinite(_) => format!(
"{}.ok_or_else(|| {:?})?",
source_expr, source_expr,
CaptureMode::Indefinite(_) => self.conformance_err_code()
format!("{}.ok_or_else(|| {:?})?", source_expr, self.conformance_err_code()), ),
} },
}) })
} }
@ -267,7 +312,13 @@ impl<'a, 'm, 'b> FunctionContext<'a, 'm, 'b> {
} }
pub fn declare_compound(&self, body: &mut Vec<Item>, name: &str, init_expr: Item) { pub fn declare_compound(&self, body: &mut Vec<Item>, name: &str, init_expr: Item) {
body.push(item(seq!["let mut ", name.to_owned(), " = ", init_expr, ";"])); body.push(item(seq![
"let mut ",
name.to_owned(),
" = ",
init_expr,
";"
]));
} }
pub fn define_atom(&mut self, body: &mut Vec<Item>, name: &str, val_expr: Item) { pub fn define_atom(&mut self, body: &mut Vec<Item>, name: &str, val_expr: Item) {
@ -291,7 +342,8 @@ impl<'a, 'm, 'b> FunctionContext<'a, 'm, 'b> {
} }
pub fn with_indefinite_mode<F: FnOnce(&mut Self) -> ()>(&mut self, f: F) -> Vec<Item> { pub fn with_indefinite_mode<F: FnOnce(&mut Self) -> ()>(&mut self, f: F) -> Vec<Item> {
let saved_mode = std::mem::replace(&mut self.capture_mode, CaptureMode::Indefinite(Vec::new())); let saved_mode =
std::mem::replace(&mut self.capture_mode, CaptureMode::Indefinite(Vec::new()));
f(self); f(self);
match std::mem::replace(&mut self.capture_mode, saved_mode) { match std::mem::replace(&mut self.capture_mode, saved_mode) {
CaptureMode::Definite => panic!("corrupt capture_mode"), CaptureMode::Definite => panic!("corrupt capture_mode"),
@ -317,7 +369,9 @@ impl<'a, 'm, 'b> FunctionContext<'a, 'm, 'b> {
} }
pub fn conformance_err_code(&self) -> Item { pub fn conformance_err_code(&self) -> Item {
return item(seq!["_support::ParseError::conformance_error", parens![ return item(seq![
escape_string(&self.fully_qualified_error_context())]]); "_support::ParseError::conformance_error",
parens![escape_string(&self.fully_qualified_error_context())]
]);
} }
} }

View File

@ -23,7 +23,7 @@ impl<T> WalkState<T> {
F: Fn(&T, &Ref) -> Option<E>, F: Fn(&T, &Ref) -> Option<E>,
R, R,
Ks: FnOnce(&mut Self, Option<E>) -> R, Ks: FnOnce(&mut Self, Option<E>) -> R,
Kf: FnOnce() -> R Kf: FnOnce() -> R,
>( >(
&mut self, &mut self,
r: &Ref, r: &Ref,

View File

@ -6,21 +6,21 @@ pub mod readers;
pub mod types; pub mod types;
pub mod unparsers; pub mod unparsers;
use crate::*;
use crate::compiler::context::*; use crate::compiler::context::*;
use crate::compiler::types::Purpose; use crate::compiler::types::Purpose;
use crate::gen::Language;
use crate::gen::schema; use crate::gen::schema;
use crate::gen::schema::*; use crate::gen::schema::*;
use crate::syntax::block::{Formatter, Item}; use crate::gen::Language;
use crate::syntax::block::constructors::*; use crate::syntax::block::constructors::*;
use crate::syntax::block::{Formatter, Item};
use crate::*;
use glob::glob; use glob::glob;
use preserves::value::BinarySource; use preserves::value::BinarySource;
use preserves::value::BytesBinarySource; use preserves::value::BytesBinarySource;
use preserves::value::Map; use preserves::value::Map;
use preserves::value::Set;
use preserves::value::Reader; use preserves::value::Reader;
use preserves::value::Set;
use std::fs::DirBuilder; use std::fs::DirBuilder;
use std::fs::File; use std::fs::File;
@ -51,8 +51,14 @@ impl std::fmt::Debug for LanguageTypes {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
f.debug_struct("LanguageTypes") f.debug_struct("LanguageTypes")
.field("fallback", &self.fallback.as_ref().map(|f| f("_"))) .field("fallback", &self.fallback.as_ref().map(|f| f("_")))
.field("definitions", &self.definitions.iter().map( .field(
|(k, f)| (k.clone(), f("_"))).collect::<Map<String, Set<String>>>()) "definitions",
&self
.definitions
.iter()
.map(|(k, f)| (k.clone(), f("_")))
.collect::<Map<String, Set<String>>>(),
)
.finish() .finish()
} }
} }
@ -89,8 +95,16 @@ impl ExternalModule {
d: &str, d: &str,
f: F, f: F,
) -> Self { ) -> Self {
if self.rust_language_types.definitions.insert(d.to_owned(), Box::new(f)).is_some() { if self
panic!("Duplicate language types definition installed: {:?} {:?}", &self.path, d); .rust_language_types
.definitions
.insert(d.to_owned(), Box::new(f))
.is_some()
{
panic!(
"Duplicate language types definition installed: {:?} {:?}",
&self.path, d
);
} }
self self
} }
@ -114,7 +128,9 @@ pub fn load_schema_or_bundle_with_purpose(
) -> io::Result<()> { ) -> io::Result<()> {
let mut inserted = Map::<ModulePath, Schema>::new(); let mut inserted = Map::<ModulePath, Schema>::new();
load_schema_or_bundle(&mut inserted, i)?; load_schema_or_bundle(&mut inserted, i)?;
for (k, v) in inserted.into_iter() { bundle.insert(k, (v, purpose)); } for (k, v) in inserted.into_iter() {
bundle.insert(k, (v, purpose));
}
Ok(()) Ok(())
} }
@ -126,23 +142,30 @@ pub fn load_schema_or_bundle_bin_with_purpose(
) -> io::Result<()> { ) -> io::Result<()> {
let mut inserted = Map::<ModulePath, Schema>::new(); let mut inserted = Map::<ModulePath, Schema>::new();
load_schema_or_bundle_bin(&mut inserted, prefix, input)?; load_schema_or_bundle_bin(&mut inserted, prefix, input)?;
for (k, v) in inserted.into_iter() { bundle.insert(k, (v, purpose)); } for (k, v) in inserted.into_iter() {
bundle.insert(k, (v, purpose));
}
Ok(()) Ok(())
} }
fn bundle_prefix(i: &PathBuf) -> io::Result<&str> { fn bundle_prefix(i: &PathBuf) -> io::Result<&str> {
i.file_stem().ok_or_else( i.file_stem()
|| io::Error::new(io::ErrorKind::InvalidData, .ok_or_else(|| {
format!("Bad schema file stem: {:?}", i)))? io::Error::new(
.to_str().ok_or_else( io::ErrorKind::InvalidData,
|| io::Error::new(io::ErrorKind::InvalidData, format!("Bad schema file stem: {:?}", i),
format!("Invalid UTF-8 in schema file name: {:?}", i))) )
})?
.to_str()
.ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidData,
format!("Invalid UTF-8 in schema file name: {:?}", i),
)
})
} }
pub fn load_schema_or_bundle( pub fn load_schema_or_bundle(bundle: &mut Map<ModulePath, Schema>, i: &PathBuf) -> io::Result<()> {
bundle: &mut Map<ModulePath, Schema>,
i: &PathBuf,
) -> io::Result<()> {
let mut f = File::open(&i)?; let mut f = File::open(&i)?;
let mut bs = vec![]; let mut bs = vec![];
f.read_to_end(&mut bs)?; f.read_to_end(&mut bs)?;
@ -166,18 +189,17 @@ pub fn load_schema_or_bundle_bin(
bundle.insert(k, v); bundle.insert(k, v);
} }
} else { } else {
return Err(io::Error::new(io::ErrorKind::InvalidData, return Err(io::Error::new(
format!("Invalid schema binary blob {:?}", prefix))); io::ErrorKind::InvalidData,
format!("Invalid schema binary blob {:?}", prefix),
));
} }
Ok(()) Ok(())
} }
impl CompilerConfig { impl CompilerConfig {
pub fn new( pub fn new(output_dir: PathBuf, fully_qualified_module_prefix: String) -> Self {
output_dir: PathBuf,
fully_qualified_module_prefix: String,
) -> Self {
CompilerConfig { CompilerConfig {
bundle: Map::new(), bundle: Map::new(),
output_dir, output_dir,
@ -201,7 +223,11 @@ impl CompilerConfig {
} }
} }
pub fn load_schemas_and_bundles(&mut self, inputs: &Vec<PathBuf>, xrefs: &Vec<PathBuf>) -> io::Result<()> { pub fn load_schemas_and_bundles(
&mut self,
inputs: &Vec<PathBuf>,
xrefs: &Vec<PathBuf>,
) -> io::Result<()> {
for i in inputs { for i in inputs {
load_schema_or_bundle_with_purpose(&mut self.bundle, i, Purpose::Codegen)?; load_schema_or_bundle_with_purpose(&mut self.bundle, i, Purpose::Codegen)?;
} }
@ -213,17 +239,24 @@ impl CompilerConfig {
pub fn load_xref_bin(&mut self, prefix: &str, bundle_or_schema: &[u8]) -> io::Result<()> { pub fn load_xref_bin(&mut self, prefix: &str, bundle_or_schema: &[u8]) -> io::Result<()> {
load_schema_or_bundle_bin_with_purpose( load_schema_or_bundle_bin_with_purpose(
&mut self.bundle, prefix, bundle_or_schema, Purpose::Xref) &mut self.bundle,
prefix,
bundle_or_schema,
Purpose::Xref,
)
} }
fn build_type_cache(&self) -> Map<Ref, types::TDefinition> { fn build_type_cache(&self) -> Map<Ref, types::TDefinition> {
self.bundle.iter().flat_map(|(modpath, s)| { self.bundle
let modpath = ModulePath(modpath.clone()); .iter()
s.0.definitions.0.iter().map(move |(name, def)| { .flat_map(|(modpath, s)| {
let ty = types::definition_type(&modpath, s.1, name, def); let modpath = ModulePath(modpath.clone());
(ty.self_ref.clone(), ty) s.0.definitions.0.iter().map(move |(name, def)| {
let ty = types::definition_type(&modpath, s.1, name, def);
(ty.self_ref.clone(), ty)
})
}) })
}).collect() .collect()
} }
fn generate_definition( fn generate_definition(
@ -247,7 +280,9 @@ impl CompilerConfig {
pub fn expand_inputs(globs: &Vec<String>) -> io::Result<Vec<PathBuf>> { pub fn expand_inputs(globs: &Vec<String>) -> io::Result<Vec<PathBuf>> {
let mut result = Vec::new(); let mut result = Vec::new();
for g in globs.iter() { for g in globs.iter() {
for p in glob(g).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, format!("{}", e)))? { for p in
glob(g).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, format!("{}", e)))?
{
result.push(p.map_err(glob::GlobError::into_error)?) result.push(p.map_err(glob::GlobError::into_error)?)
} }
} }
@ -271,7 +306,10 @@ fn write_if_changed(output_path: &PathBuf, contents: &[u8]) -> io::Result<()> {
impl Ref { impl Ref {
pub fn qualify(&self, default_module_path: &schema::ModulePath) -> Ref { pub fn qualify(&self, default_module_path: &schema::ModulePath) -> Ref {
if self.module.0.is_empty() { if self.module.0.is_empty() {
Ref { module: default_module_path.clone(), name: self.name.clone() } Ref {
module: default_module_path.clone(),
name: self.name.clone(),
}
} else { } else {
self.clone() self.clone()
} }
@ -294,10 +332,17 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
let mut output_path = config.output_dir.clone(); let mut output_path = config.output_dir.clone();
output_path.extend(k); output_path.extend(k);
let module_name = output_path.file_stem().unwrap().to_str().unwrap().to_owned(); let module_name = output_path
.file_stem()
.unwrap()
.to_str()
.unwrap()
.to_owned();
let module_name = names::render_modname(&module_name); let module_name = names::render_modname(&module_name);
output_path.set_file_name(format!("{}.rs", module_name)); output_path.set_file_name(format!("{}.rs", module_name));
DirBuilder::new().recursive(true).create(output_path.parent().unwrap())?; DirBuilder::new()
.recursive(true)
.create(output_path.parent().unwrap())?;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -319,23 +364,28 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
let mut lines: Vec<String> = Vec::new(); let mut lines: Vec<String> = Vec::new();
lines.push(Formatter::to_string(vertical(false, seq![ lines.push(Formatter::to_string(vertical(
"#![allow(unused_parens)]", false,
"#![allow(unused_imports)]"]))); seq!["#![allow(unused_parens)]", "#![allow(unused_imports)]"],
)));
if config.rustfmt_skip { if config.rustfmt_skip {
lines.push("#![cfg_attr(rustfmt, rustfmt_skip)]".to_owned()); lines.push("#![cfg_attr(rustfmt, rustfmt_skip)]".to_owned());
} }
lines.push(Formatter::to_string(vertical(false, seq![ lines.push(Formatter::to_string(vertical(
"", false,
"use std::convert::TryFrom;", seq![
format!("use {}::support as _support;", &config.support_crate), "",
"use _support::Deserialize;", "use std::convert::TryFrom;",
"use _support::Parse;", format!("use {}::support as _support;", &config.support_crate),
"use _support::Unparse;", "use _support::Deserialize;",
"use _support::preserves;", "use _support::Parse;",
"use preserves::value::Domain;", "use _support::Unparse;",
"use preserves::value::NestedValue;", "use _support::preserves;",
""]))); "use preserves::value::Domain;",
"use preserves::value::NestedValue;",
""
],
)));
let mut emit_items = |items: Vec<Item>| { let mut emit_items = |items: Vec<Item>| {
if !items.is_empty() { if !items.is_empty() {
@ -344,7 +394,11 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
} }
}; };
emit_items(generated.remove(&ModuleContextMode::TargetModule).unwrap()); emit_items(generated.remove(&ModuleContextMode::TargetModule).unwrap());
emit_items(generated.remove(&ModuleContextMode::TargetToplevel).unwrap()); emit_items(
generated
.remove(&ModuleContextMode::TargetToplevel)
.unwrap(),
);
emit_items(generated.remove(&ModuleContextMode::TargetGeneric).unwrap()); emit_items(generated.remove(&ModuleContextMode::TargetGeneric).unwrap());
{ {
@ -367,41 +421,77 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
if *module_purpose != Purpose::Codegen { if *module_purpose != Purpose::Codegen {
continue; continue;
} }
lines.push(format!("pub mod {};", names::render_modname(modpath.last().unwrap()))); lines.push(format!(
"pub mod {};",
names::render_modname(modpath.last().unwrap())
));
} }
lines.push("".to_owned()); lines.push("".to_owned());
lines.push(format!("use {}::support as _support;", &config.support_crate)); lines.push(format!(
"use {}::support as _support;",
&config.support_crate
));
lines.push("use _support::preserves;".to_owned()); lines.push("use _support::preserves;".to_owned());
lines.push("".to_owned()); lines.push("".to_owned());
lines.push("#[allow(non_snake_case)]".to_owned()); lines.push("#[allow(non_snake_case)]".to_owned());
lines.push(Formatter::to_string(item(seq![ lines.push(Formatter::to_string(item(seq![
"pub struct ", b.language_struct_name(), anglebrackets!["N: preserves::value::NestedValue"], " ", "pub struct ",
vertical(false, braces(b.literals.iter().map( b.language_struct_name(),
|(value, name)| item(format!("pub {}: N /* {:?} */", name, value))).collect())) anglebrackets!["N: preserves::value::NestedValue"],
" ",
vertical(
false,
braces(
b.literals
.iter()
.map(|(value, name)| item(format!("pub {}: N /* {:?} */", name, value)))
.collect()
)
)
]))); ])));
lines.push("".to_owned()); lines.push("".to_owned());
lines.push(Formatter::to_string(item(seq![ lines.push(Formatter::to_string(item(seq![
"impl", anglebrackets!["N: preserves::value::NestedValue"], "impl",
" Default for ", b.language_struct_name(), "<N> ", codeblock![ anglebrackets!["N: preserves::value::NestedValue"],
seq!["fn default() -> Self ", codeblock![ " Default for ",
seq![b.language_struct_name(), " ", vertical(false, braces(b.literals.iter().map(|(value, name)| { b.language_struct_name(),
let bs = preserves::value::PackedWriter::encode_iovalue(&value).unwrap(); "<N> ",
item(format!("{}: /* {:?} */ _support::decode_lit(&{:?}).unwrap()", codeblock![seq![
name, "fn default() -> Self ",
value, codeblock![seq![
bs)) b.language_struct_name(),
}).collect()))] " ",
vertical(
false,
braces(
b.literals
.iter()
.map(|(value, name)| {
let bs = preserves::value::PackedWriter::encode_iovalue(&value)
.unwrap();
item(format!(
"{}: /* {:?} */ _support::decode_lit(&{:?}).unwrap()",
name, value, bs
))
})
.collect()
)
)
]] ]]
] ]]
]))); ])));
lines.push("".to_owned()); lines.push("".to_owned());
{ {
let mut b = Bundle { modules: Modules(Map::new()) }; let mut b = Bundle {
modules: Modules(Map::new()),
};
for (modpath, (schema, purpose)) in config.bundle.iter() { for (modpath, (schema, purpose)) in config.bundle.iter() {
if *purpose == Purpose::Codegen { if *purpose == Purpose::Codegen {
b.modules.0.insert(ModulePath(modpath.clone()), schema.clone()); b.modules
.0
.insert(ModulePath(modpath.clone()), schema.clone());
} }
} }
let b_value = Language::default().unparse(&b); let b_value = Language::default().unparse(&b);
@ -416,9 +506,8 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
hex_encoded_bundle.push_str(&format!("\\x{:02x}", b)); hex_encoded_bundle.push_str(&format!("\\x{:02x}", b));
} }
lines.push(Formatter::to_string(item(seq![ lines.push(Formatter::to_string(item(seq![
"pub fn _bundle() -> &'static [u8] ", codeblock![ "pub fn _bundle() -> &'static [u8] ",
seq!["b\"", hex_encoded_bundle, "\""] codeblock![seq!["b\"", hex_encoded_bundle, "\""]]
]
]))); ])));
} }
lines.push("".to_owned()); lines.push("".to_owned());

View File

@ -1,7 +1,7 @@
use crate::*;
use crate::gen::schema::*; use crate::gen::schema::*;
use crate::syntax::block::Item;
use crate::syntax::block::constructors::*; use crate::syntax::block::constructors::*;
use crate::syntax::block::Item;
use crate::*;
use super::context::FunctionContext; use super::context::FunctionContext;
use super::context::ModuleContext; use super::context::ModuleContext;
@ -14,7 +14,12 @@ use super::types::*;
pub struct ParserPlugin; pub struct ParserPlugin;
impl compiler::Plugin for ParserPlugin { impl compiler::Plugin for ParserPlugin {
fn generate_definition(&self, module_ctxt: &mut ModuleContext, definition_name: &str, definition: &Definition) { fn generate_definition(
&self,
module_ctxt: &mut ModuleContext,
definition_name: &str,
definition: &Definition,
) {
if let ModuleContextMode::TargetGeneric = module_ctxt.mode { if let ModuleContextMode::TargetGeneric = module_ctxt.mode {
gen_definition_parser(module_ctxt, definition_name, definition) gen_definition_parser(module_ctxt, definition_name, definition)
} }
@ -24,62 +29,112 @@ impl compiler::Plugin for ParserPlugin {
pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) { pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) {
let ty = definition_type(&m.module_path, Purpose::Codegen, n, d); let ty = definition_type(&m.module_path, Purpose::Codegen, n, d);
m.define_function( m.define_function(n, |mut ctxt| {
n, let mut body = vec![];
|mut ctxt| {
let mut body = vec![];
match d { match d {
Definition::Or { pattern_0, pattern_1, pattern_n } => { Definition::Or {
let mut ps = vec![&**pattern_0, &**pattern_1]; pattern_0,
ps.extend(pattern_n); pattern_1,
for NamedAlternative { variant_label: name, pattern: pat } in ps { pattern_n,
let fname = seq!["parse_", names::render_fieldname(n), "_", names::render_fieldname(name)]; } => {
let ctorname = item(name![names::render_constructor(n), names::render_constructor(name)]); let mut ps = vec![&**pattern_0, &**pattern_1];
ctxt.m.define_function( ps.extend(pattern_n);
&(n.to_owned() + "::" + name), for NamedAlternative {
|mut ctxt| { variant_label: name,
let mut body = Vec::new(); pattern: pat,
let dest = pattern_parser(&mut ctxt, pat, "value", None, &mut body); } in ps
let dest = dest.as_ref().map(String::as_str); {
construct(&ctxt, ctorname, false, &pattern_type(pat), dest, &mut body); 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(&(n.to_owned() + "::" + name), |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, false, &pattern_type(pat), dest, &mut body);
item(seq!["fn ", fname.clone(), item(seq![
ctxt.m.parse_unparse_generic_decls(&ty), "fn ",
"(_ctxt: _L, value: &", ctxt.m.any_type(), ") -> ", fname.clone(),
"std::result::Result<", ctxt.m.parse_unparse_generic_decls(&ty),
names::render_constructor(n), ty.generic_arg(ctxt.m), "(_ctxt: _L, value: &",
", _support::ParseError> ", ctxt.m.any_type(),
codeblock(body)]) ") -> ",
}); "std::result::Result<",
body.push(item(seq!["if let Ok(r) = ", fname, "(_ctxt, value) { return Ok(r); }"])); names::render_constructor(n),
} ty.generic_arg(ctxt.m),
body.push(item(seq![ctxt.err_code()])); ", _support::ParseError> ",
} codeblock(body)
Definition::And { pattern_0, pattern_1, pattern_n } => { ])
let mut ps = vec![&**pattern_0, &**pattern_1]; });
ps.extend(pattern_n); body.push(item(seq![
for e in &ps { "if let Ok(r) = ",
named_pattern_parser(&mut ctxt, e, "value", None, &mut body); fname,
} "(_ctxt, value) { return Ok(r); }"
construct(&ctxt, item(names::render_constructor(n)), true, &record_type(&ps), None, &mut body); ]));
}
Definition::Pattern(p) => {
let dest = pattern_parser(&mut ctxt, p, "value", None, &mut body);
let dest = dest.as_ref().map(String::as_str);
construct(&ctxt, item(names::render_constructor(n)), true, &pattern_type(p), dest, &mut body);
} }
body.push(item(seq![ctxt.err_code()]));
} }
Definition::And {
pattern_0,
pattern_1,
pattern_n,
} => {
let mut ps = vec![&**pattern_0, &**pattern_1];
ps.extend(pattern_n);
for e in &ps {
named_pattern_parser(&mut ctxt, e, "value", None, &mut body);
}
construct(
&ctxt,
item(names::render_constructor(n)),
true,
&record_type(&ps),
None,
&mut body,
);
}
Definition::Pattern(p) => {
let dest = pattern_parser(&mut ctxt, p, "value", None, &mut body);
let dest = dest.as_ref().map(String::as_str);
construct(
&ctxt,
item(names::render_constructor(n)),
true,
&pattern_type(p),
dest,
&mut body,
);
}
}
item(seq!["impl", item(seq![
ctxt.m.parse_unparse_generic_decls(&ty), "impl",
" _support::Parse", anglebrackets!["_L", ctxt.m.any_type()], " for ", ctxt.m.parse_unparse_generic_decls(&ty),
names::render_constructor(n), ty.generic_arg(ctxt.m), " ", " _support::Parse",
codeblock![ anglebrackets!["_L", ctxt.m.any_type()],
seq!["fn parse(_ctxt: _L, value: &", ctxt.m.any_type(), ")", " for ",
" -> std::result::Result<Self, _support::ParseError> ", names::render_constructor(n),
codeblock(body)]]]) ty.generic_arg(ctxt.m),
}); " ",
codeblock![seq![
"fn parse(_ctxt: _L, value: &",
ctxt.m.any_type(),
")",
" -> std::result::Result<Self, _support::ParseError> ",
codeblock(body)
]]
])
});
} }
fn construct( fn construct(
@ -91,30 +146,42 @@ fn construct(
body: &mut Vec<Item>, body: &mut Vec<Item>,
) { ) {
match ty { match ty {
TSimple::Field(TField::Unit) => TSimple::Field(TField::Unit) => body.push(item(seq!["Ok(", ctorname, ")"])),
body.push(item(seq!["Ok(", ctorname, ")"])), TSimple::Field(fieldty) => body.push(item(seq![
TSimple::Field(fieldty) => "Ok(",
body.push(item(seq!["Ok(", ctorname, parens![store_wrap(is_struct, fieldty, dest.unwrap())], ")"])), ctorname,
TSimple::Record(_) => parens![store_wrap(is_struct, fieldty, dest.unwrap())],
body.push(item(seq!["Ok(", ctorname, " ", braces( ")"
ctxt.captures.iter().map( ])),
|c| item(seq![c.field_name.clone(), ": ", store_wrap(is_struct, &c.ty, &c.source_expr)])).collect()), TSimple::Record(_) => body.push(item(seq![
")"])), "Ok(",
ctorname,
" ",
braces(
ctxt.captures
.iter()
.map(|c| item(seq![
c.field_name.clone(),
": ",
store_wrap(is_struct, &c.ty, &c.source_expr)
]))
.collect()
),
")"
])),
} }
} }
fn store_wrap(is_struct: bool, ty: &TField, expr: &str) -> String { fn store_wrap(is_struct: bool, ty: &TField, expr: &str) -> String {
match ty { match ty {
TField::Unit TField::Unit | TField::Array(_) | TField::Set(_) | TField::Map(_, _) => expr.to_owned(),
| TField::Array(_) TField::Ref(_) => {
| TField::Set(_)
| TField::Map(_, _) => expr.to_owned(),
TField::Ref(_) =>
if is_struct { if is_struct {
expr.to_owned() expr.to_owned()
} else { } else {
format!("std::boxed::Box::new({})", expr) format!("std::boxed::Box::new({})", expr)
}, }
}
TField::Base(_) | TField::Any | TField::Embedded => format!("{}.clone()", expr), TField::Base(_) | TField::Any | TField::Embedded => format!("{}.clone()", expr),
} }
} }
@ -131,7 +198,7 @@ fn simple_pattern_parser(
SimplePattern::Any => { SimplePattern::Any => {
ctxt.define_atom(body, &dest, item(src.to_owned())); ctxt.define_atom(body, &dest, item(src.to_owned()));
dest dest
}, }
SimplePattern::Atom { atom_kind: k } => { SimplePattern::Atom { atom_kind: k } => {
let converter = match &**k { let converter = match &**k {
AtomKind::Boolean => "to_boolean", AtomKind::Boolean => "to_boolean",
@ -142,45 +209,82 @@ fn simple_pattern_parser(
AtomKind::ByteString => "to_bytestring", AtomKind::ByteString => "to_bytestring",
AtomKind::Symbol => "to_symbol", AtomKind::Symbol => "to_symbol",
}; };
ctxt.define_atom(body, &dest, item(seq![src.to_owned(), ".value().", converter, "()?"])); ctxt.define_atom(
body,
&dest,
item(seq![src.to_owned(), ".value().", converter, "()?"]),
);
dest dest
}, }
SimplePattern::Embedded { .. } => { SimplePattern::Embedded { .. } => {
ctxt.define_atom(body, &dest, item(seq![ ctxt.define_atom(
parens![seq![src.to_owned(), ".value().to_embedded()?"]]])); body,
&dest,
item(seq![parens![seq![
src.to_owned(),
".value().to_embedded()?"
]]]),
);
dest dest
}, }
SimplePattern::Lit { value } => { SimplePattern::Lit { value } => {
body.push(item(seq!["if ", src.to_owned(), " != ", ctxt.m.define_literal(value), body.push(item(seq![
" { return ", ctxt.err_code(), "; }"])); "if ",
src.to_owned(),
" != ",
ctxt.m.define_literal(value),
" { return ",
ctxt.err_code(),
"; }"
]));
ctxt.define_atom(body, &dest, item("()")); ctxt.define_atom(body, &dest, item("()"));
dest dest
}, }
SimplePattern::Seqof { pattern } => { SimplePattern::Seqof { pattern } => {
let (src, n) = sequenceify(ctxt, src, sequence_base, body); let (src, n) = sequenceify(ctxt, src, sequence_base, body);
let tmp = ctxt.gentempname(); let tmp = ctxt.gentempname();
let mut inner = Vec::new(); let mut inner = Vec::new();
let item_dest = simple_pattern_parser(ctxt, pattern, &tmp, None, &mut inner); let item_dest = simple_pattern_parser(ctxt, pattern, &tmp, None, &mut inner);
inner.push(item(seq![dest.to_owned(), ".push(", inner.push(item(seq![
store_wrap(true, &field_type(pattern), &item_dest), ");"])); dest.to_owned(),
".push(",
store_wrap(true, &field_type(pattern), &item_dest),
");"
]));
ctxt.declare_compound(body, &dest, item("std::vec::Vec::new()")); ctxt.declare_compound(body, &dest, item("std::vec::Vec::new()"));
body.push(item(seq!["for ", tmp.to_owned(), body.push(item(seq![
" in &", src.to_owned(), brackets![seq![n.to_string() , ".."]], "for ",
" ", codeblock(inner)])); tmp.to_owned(),
" in &",
src.to_owned(),
brackets![seq![n.to_string(), ".."]],
" ",
codeblock(inner)
]));
dest dest
}, }
SimplePattern::Setof { pattern } => { SimplePattern::Setof { pattern } => {
let tmp = ctxt.gentempname(); let tmp = ctxt.gentempname();
let mut inner = Vec::new(); let mut inner = Vec::new();
let item_dest = simple_pattern_parser(ctxt, pattern, &tmp, None, &mut inner); let item_dest = simple_pattern_parser(ctxt, pattern, &tmp, None, &mut inner);
inner.push(item(seq![dest.to_owned(), ".insert(", inner.push(item(seq![
store_wrap(true, &field_type(pattern), &item_dest), ");"])); dest.to_owned(),
".insert(",
store_wrap(true, &field_type(pattern), &item_dest),
");"
]));
ctxt.declare_compound(body, &dest, item("preserves::value::Set::new()")); ctxt.declare_compound(body, &dest, item("preserves::value::Set::new()"));
body.push(item(seq!["for ", tmp.to_owned(), body.push(item(seq![
" in ", src.to_owned(), ".value().to_set()?", "for ",
" ", codeblock(inner)])); tmp.to_owned(),
" in ",
src.to_owned(),
".value().to_set()?",
" ",
codeblock(inner)
]));
dest dest
}, }
SimplePattern::Dictof { key, value } => { SimplePattern::Dictof { key, value } => {
let tmp_key = ctxt.gentempname(); let tmp_key = ctxt.gentempname();
let tmp_value = ctxt.gentempname(); let tmp_value = ctxt.gentempname();
@ -188,22 +292,37 @@ fn simple_pattern_parser(
let key_dest = simple_pattern_parser(ctxt, key, &tmp_key, None, &mut inner); let key_dest = simple_pattern_parser(ctxt, key, &tmp_key, None, &mut inner);
let value_dest = simple_pattern_parser(ctxt, value, &tmp_value, None, &mut inner); let value_dest = simple_pattern_parser(ctxt, value, &tmp_value, None, &mut inner);
inner.push(item(seq![ inner.push(item(seq![
dest.to_owned(), ".insert(", dest.to_owned(),
store_wrap(true, &field_type(key), &key_dest), ", ", ".insert(",
store_wrap(true, &field_type(value), &value_dest), ");"])); store_wrap(true, &field_type(key), &key_dest),
", ",
store_wrap(true, &field_type(value), &value_dest),
");"
]));
ctxt.declare_compound(body, &dest, item("preserves::value::Map::new()")); ctxt.declare_compound(body, &dest, item("preserves::value::Map::new()"));
body.push(item(seq!["for (", tmp_key.to_owned(), ", ", tmp_value.to_owned(), ")", body.push(item(seq![
" in ", src.to_owned(), ".value().to_dictionary()?", "for (",
" ", codeblock(inner)])); tmp_key.to_owned(),
", ",
tmp_value.to_owned(),
")",
" in ",
src.to_owned(),
".value().to_dictionary()?",
" ",
codeblock(inner)
]));
dest dest
}, }
SimplePattern::Ref(r) => { SimplePattern::Ref(r) => {
let tf = name![ctxt.m.render_ref(&**r, RefRenderStyle::Bare), "parse"]; let tf = name![ctxt.m.render_ref(&**r, RefRenderStyle::Bare), "parse"];
ctxt.define_atom(body, ctxt.define_atom(
&dest, body,
item(seq![tf, parens!["_ctxt", src.to_owned()], "?"])); &dest,
item(seq![tf, parens!["_ctxt", src.to_owned()], "?"]),
);
dest dest
}, }
} }
} }
@ -217,7 +336,11 @@ fn sequenceify(
Some(n) => (src.to_owned(), n), Some(n) => (src.to_owned(), n),
None => { None => {
let tmp = ctxt.gentempname(); let tmp = ctxt.gentempname();
ctxt.define_atom(body, &tmp, item(seq![src.to_owned(), ".value().to_sequence()?"])); ctxt.define_atom(
body,
&tmp,
item(seq![src.to_owned(), ".value().to_sequence()?"]),
);
(tmp, 0) (tmp, 0)
} }
} }
@ -233,10 +356,21 @@ fn fixed_sequence_parser(
let mut i = base; let mut i = base;
let required_count = ps.len(); let required_count = ps.len();
if required_count > 0 { if required_count > 0 {
body.push(item(seq!["if ", src.to_owned(), ".len()", body.push(item(seq![
if base > 0 { seq![" - ", base.to_string()] } else { seq![] }, "if ",
" < ", required_count.to_string(), src.to_owned(),
" { return ", ctxt.err_code(), "; }"])); ".len()",
if base > 0 {
seq![" - ", base.to_string()]
} else {
seq![]
},
" < ",
required_count.to_string(),
" { return ",
ctxt.err_code(),
"; }"
]));
} }
for p in ps { for p in ps {
named_pattern_parser(ctxt, p, &format!("(&{}[{}])", src, i), None, body); named_pattern_parser(ctxt, p, &format!("(&{}[{}])", src, i), None, body);
@ -254,9 +388,9 @@ fn named_pattern_parser(
match p { match p {
NamedPattern::Anonymous(p) => { NamedPattern::Anonymous(p) => {
pattern_parser(ctxt, p, src, sequence_base, body); pattern_parser(ctxt, p, src, sequence_base, body);
}, }
NamedPattern::Named(b) => { NamedPattern::Named(b) => {
let Binding { name, pattern} = &**b; let Binding { name, pattern } = &**b;
let dest = simple_pattern_parser(ctxt, pattern, src, sequence_base, body); let dest = simple_pattern_parser(ctxt, pattern, src, sequence_base, body);
let capture_ty = field_type(pattern); let capture_ty = field_type(pattern);
ctxt.capture(names::render_fieldname(name), capture_ty, dest); ctxt.capture(names::render_fieldname(name), capture_ty, dest);
@ -272,39 +406,63 @@ fn pattern_parser(
body: &mut Vec<Item>, body: &mut Vec<Item>,
) -> Option<String> { ) -> Option<String> {
match p { match p {
Pattern::SimplePattern(s) => Pattern::SimplePattern(s) => Some(simple_pattern_parser(ctxt, s, src, sequence_base, body)),
Some(simple_pattern_parser(ctxt, s, src, sequence_base, body)),
Pattern::CompoundPattern(c) => { Pattern::CompoundPattern(c) => {
match &**c { match &**c {
CompoundPattern::Rec { label, fields } => { CompoundPattern::Rec { label, fields } => {
let rtmp = ctxt.gentempname(); let rtmp = ctxt.gentempname();
ctxt.define_atom(body, &rtmp, item(seq![src.to_owned(), ".value().to_record(None)?"])); ctxt.define_atom(
body,
&rtmp,
item(seq![src.to_owned(), ".value().to_record(None)?"]),
);
named_pattern_parser(ctxt, &**label, &format!("{}.label()", rtmp), None, body); named_pattern_parser(ctxt, &**label, &format!("{}.label()", rtmp), None, body);
named_pattern_parser(ctxt, &**fields, &format!("{}.fields()", rtmp), Some(0), body); named_pattern_parser(
}, ctxt,
&**fields,
&format!("{}.fields()", rtmp),
Some(0),
body,
);
}
CompoundPattern::Tuple { patterns } => { CompoundPattern::Tuple { patterns } => {
let (src, n) = sequenceify(ctxt, src, sequence_base, body); let (src, n) = sequenceify(ctxt, src, sequence_base, body);
fixed_sequence_parser(ctxt, n, patterns, &src, body); fixed_sequence_parser(ctxt, n, patterns, &src, body);
}, }
CompoundPattern::TuplePrefix { fixed, variable } => { CompoundPattern::TuplePrefix { fixed, variable } => {
let (src, n) = sequenceify(ctxt, src, sequence_base, body); let (src, n) = sequenceify(ctxt, src, sequence_base, body);
fixed_sequence_parser(ctxt, n, fixed, &src, body); fixed_sequence_parser(ctxt, n, fixed, &src, body);
named_pattern_parser(ctxt, &promote(variable), &src, Some(n + fixed.len()), body); named_pattern_parser(
}, ctxt,
&promote(variable),
&src,
Some(n + fixed.len()),
body,
);
}
CompoundPattern::Dict { entries } => { CompoundPattern::Dict { entries } => {
let dtmp = ctxt.gentempname(); let dtmp = ctxt.gentempname();
ctxt.define_atom(body, &dtmp, item(seq![src.to_owned(), ".value().to_dictionary()?"])); ctxt.define_atom(
body,
&dtmp,
item(seq![src.to_owned(), ".value().to_dictionary()?"]),
);
for (key_lit, value_pat) in entries.0.iter() { for (key_lit, value_pat) in entries.0.iter() {
let vtmp = ctxt.gentempname(); let vtmp = ctxt.gentempname();
let init_expr = item(seq![ let init_expr = item(seq![
dtmp.to_owned(), ".get", parens![ctxt.m.define_literal(key_lit)], dtmp.to_owned(),
".ok_or_else(|| ", ctxt.conformance_err_code(), ")?"]); ".get",
parens![ctxt.m.define_literal(key_lit)],
".ok_or_else(|| ",
ctxt.conformance_err_code(),
")?"
]);
ctxt.define_atom(body, &vtmp, init_expr); ctxt.define_atom(body, &vtmp, init_expr);
named_pattern_parser(ctxt, &promote(value_pat), &vtmp, None, body); named_pattern_parser(ctxt, &promote(value_pat), &vtmp, None, body);
} }
} }
} }
None None
}, }
} }
} }

View File

@ -1,9 +1,9 @@
use crate::*;
use crate::gen::schema::*; use crate::gen::schema::*;
use crate::syntax::block::Item;
use crate::syntax::block::escape_string;
use crate::syntax::block::escape_bytes;
use crate::syntax::block::constructors::*; use crate::syntax::block::constructors::*;
use crate::syntax::block::escape_bytes;
use crate::syntax::block::escape_string;
use crate::syntax::block::Item;
use crate::*;
use preserves::value::AtomClass; use preserves::value::AtomClass;
use preserves::value::CompoundClass; use preserves::value::CompoundClass;
@ -22,7 +22,12 @@ use super::types::*;
pub struct ReaderPlugin; pub struct ReaderPlugin;
impl compiler::Plugin for ReaderPlugin { impl compiler::Plugin for ReaderPlugin {
fn generate_definition(&self, module_ctxt: &mut ModuleContext, definition_name: &str, definition: &Definition) { fn generate_definition(
&self,
module_ctxt: &mut ModuleContext,
definition_name: &str,
definition: &Definition,
) {
if let ModuleContextMode::TargetGeneric = module_ctxt.mode { if let ModuleContextMode::TargetGeneric = module_ctxt.mode {
gen_definition_reader(module_ctxt, definition_name, definition) gen_definition_reader(module_ctxt, definition_name, definition)
} }
@ -56,7 +61,11 @@ impl BoundaryTracker {
) -> Self { ) -> Self {
let tracker_name = ctxt.gentempname(); let tracker_name = ctxt.gentempname();
body.push(item(open_expr)); body.push(item(open_expr));
body.push(item(seq!["let mut ", tracker_name.clone(), " = _support::B::Type::default();"])); body.push(item(seq![
"let mut ",
tracker_name.clone(),
" = _support::B::Type::default();"
]));
BoundaryTracker { BoundaryTracker {
tracker_name, tracker_name,
item_expr, item_expr,
@ -64,93 +73,151 @@ impl BoundaryTracker {
} }
fn emit_boundary(&self, body: &mut Vec<Item>) { fn emit_boundary(&self, body: &mut Vec<Item>) {
body.push(item(seq![self.tracker_name.clone(), ".shift(Some(", self.item_expr, "));"])); body.push(item(seq![
self.tracker_name.clone(),
".shift(Some(",
self.item_expr,
"));"
]));
body.push(item(seq!["r.boundary(&", self.tracker_name.clone(), ")?;"])); body.push(item(seq!["r.boundary(&", self.tracker_name.clone(), ")?;"]));
} }
fn emit_loop(&self, body: &mut Vec<Item>, inner: Vec<Item>) { fn emit_loop(&self, body: &mut Vec<Item>, inner: Vec<Item>) {
body.push(item(seq![ body.push(item(seq![
"while !r.close_compound", parens![ "while !r.close_compound",
parens![
seq!["&mut ", self.tracker_name.clone()], seq!["&mut ", self.tracker_name.clone()],
seq!["&", self.item_expr]], "? ", seq!["&", self.item_expr]
codeblock(inner)])) ],
"? ",
codeblock(inner)
]))
} }
} }
pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) { pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) {
let ty = definition_type(&m.module_path, Purpose::Codegen, n, d); let ty = definition_type(&m.module_path, Purpose::Codegen, n, d);
m.define_function( m.define_function(n, |mut ctxt| {
n, let mut body = vec![];
|mut ctxt| {
let mut body = vec![];
match d { match d {
Definition::Or { pattern_0, pattern_1, pattern_n } => { Definition::Or {
let mut ps = vec![&**pattern_0, &**pattern_1]; pattern_0,
ps.extend(pattern_n); pattern_1,
ctxt.define_atom(&mut body, "_mark", item("r.mark()?")); pattern_n,
for NamedAlternative { variant_label: name, pattern: pat } in ps { } => {
let fname = seq!["read_", names::render_fieldname(n), "_", names::render_fieldname(name)]; let mut ps = vec![&**pattern_0, &**pattern_1];
let ctorname = item(name![names::render_constructor(n), names::render_constructor(name)]); ps.extend(pattern_n);
ctxt.m.define_function( ctxt.define_atom(&mut body, "_mark", item("r.mark()?"));
&(n.to_owned() + "::" + name), for NamedAlternative {
|mut ctxt| { variant_label: name,
let mut body = Vec::new(); pattern: pat,
let dest = pattern_reader(&mut ctxt, pat, None, &mut body); } in ps
let dest = dest.as_ref().map(String::as_str); {
construct(&ctxt, ctorname, false, &pattern_type(pat), dest, &mut body); let fname = seq![
item(seq![ "read_",
"fn ", fname.clone(), anglebrackets![ names::render_fieldname(n),
"'de", "_",
seq![ctxt.m.any_type(), ": preserves::value::NestedValue"], names::render_fieldname(name)
seq!["R: _support::Reader<'de, ", ctxt.m.any_type(), ">"]], ];
"(r: &mut R) -> ", let ctorname = item(name![
"std::result::Result<", names::render_constructor(n),
names::render_constructor(n), ty.generic_arg(ctxt.m), names::render_constructor(name)
", _support::ParseError> ", ]);
codeblock(body)]) ctxt.m
}); .define_function(&(n.to_owned() + "::" + name), |mut ctxt| {
body.push(item(seq![ let mut body = Vec::new();
"match ", fname, "(r) { ", let dest = pattern_reader(&mut ctxt, pat, None, &mut body);
"Err(e) if e.is_conformance_error() => r.restore(&_mark)?, ", let dest = dest.as_ref().map(String::as_str);
"result => return result }"])); construct(&ctxt, ctorname, false, &pattern_type(pat), dest, &mut body);
} item(seq![
body.push(item(seq![ctxt.err_code()])); "fn ",
} fname.clone(),
Definition::And { pattern_0, pattern_1, pattern_n } => { anglebrackets![
let mut ps = vec![&**pattern_0, &**pattern_1]; "'de",
let mut need_restore = false; seq![ctxt.m.any_type(), ": preserves::value::NestedValue"],
ps.extend(pattern_n); seq!["R: _support::Reader<'de, ", ctxt.m.any_type(), ">"]
ctxt.define_atom(&mut body, "_mark", item("r.mark()?")); ],
for e in &ps { "(r: &mut R) -> ",
if need_restore { "std::result::Result<",
body.push(item("r.restore(&_mark)?;")); names::render_constructor(n),
} else { ty.generic_arg(ctxt.m),
need_restore = true; ", _support::ParseError> ",
} codeblock(body)
named_pattern_reader(&mut ctxt, e, None, &mut body); ])
} });
construct(&ctxt, item(names::render_constructor(n)), true, &record_type(&ps), None, &mut body); body.push(item(seq![
} "match ",
Definition::Pattern(p) => { fname,
let dest = pattern_reader(&mut ctxt, p, None, &mut body); "(r) { ",
let dest = dest.as_ref().map(String::as_str); "Err(e) if e.is_conformance_error() => r.restore(&_mark)?, ",
construct(&ctxt, item(names::render_constructor(n)), true, &pattern_type(p), dest, &mut body); "result => return result }"
]));
} }
body.push(item(seq![ctxt.err_code()]));
} }
Definition::And {
pattern_0,
pattern_1,
pattern_n,
} => {
let mut ps = vec![&**pattern_0, &**pattern_1];
let mut need_restore = false;
ps.extend(pattern_n);
ctxt.define_atom(&mut body, "_mark", item("r.mark()?"));
for e in &ps {
if need_restore {
body.push(item("r.restore(&_mark)?;"));
} else {
need_restore = true;
}
named_pattern_reader(&mut ctxt, e, None, &mut body);
}
construct(
&ctxt,
item(names::render_constructor(n)),
true,
&record_type(&ps),
None,
&mut body,
);
}
Definition::Pattern(p) => {
let dest = pattern_reader(&mut ctxt, p, None, &mut body);
let dest = dest.as_ref().map(String::as_str);
construct(
&ctxt,
item(names::render_constructor(n)),
true,
&pattern_type(p),
dest,
&mut body,
);
}
}
item(seq![ item(seq![
"impl", anglebrackets![seq![ctxt.m.any_type(), ": preserves::value::NestedValue"]], "impl",
" _support::Deserialize", anglebrackets![ctxt.m.any_type()], " for ", anglebrackets![seq![ctxt.m.any_type(), ": preserves::value::NestedValue"]],
names::render_constructor(n), ty.generic_arg(ctxt.m), " ", codeblock![ " _support::Deserialize",
seq!["fn deserialize", anglebrackets![ctxt.m.any_type()],
anglebrackets!["'de", " for ",
seq!["R: _support::Reader<'de, ", ctxt.m.any_type(), ">"]], names::render_constructor(n),
"(r: &mut R) -> ", ty.generic_arg(ctxt.m),
"std::result::Result<Self, _support::ParseError> ", " ",
codeblock(body)]]]) codeblock![seq![
}); "fn deserialize",
anglebrackets![
"'de",
seq!["R: _support::Reader<'de, ", ctxt.m.any_type(), ">"]
],
"(r: &mut R) -> ",
"std::result::Result<Self, _support::ParseError> ",
codeblock(body)
]]
])
});
} }
fn construct( fn construct(
@ -162,30 +229,42 @@ fn construct(
body: &mut Vec<Item>, body: &mut Vec<Item>,
) { ) {
match ty { match ty {
TSimple::Field(TField::Unit) => TSimple::Field(TField::Unit) => body.push(item(seq!["Ok(", ctorname, ")"])),
body.push(item(seq!["Ok(", ctorname, ")"])), TSimple::Field(fieldty) => body.push(item(seq![
TSimple::Field(fieldty) => "Ok(",
body.push(item(seq!["Ok(", ctorname, parens![store_wrap(is_struct, fieldty, dest.unwrap())], ")"])), ctorname,
TSimple::Record(_) => parens![store_wrap(is_struct, fieldty, dest.unwrap())],
body.push(item(seq!["Ok(", ctorname, " ", braces( ")"
ctxt.captures.iter().map( ])),
|c| item(seq![c.field_name.clone(), ": ", store_wrap(is_struct, &c.ty, &c.source_expr)])).collect()), TSimple::Record(_) => body.push(item(seq![
")"])), "Ok(",
ctorname,
" ",
braces(
ctxt.captures
.iter()
.map(|c| item(seq![
c.field_name.clone(),
": ",
store_wrap(is_struct, &c.ty, &c.source_expr)
]))
.collect()
),
")"
])),
} }
} }
fn store_wrap(is_struct: bool, ty: &TField, expr: &str) -> String { fn store_wrap(is_struct: bool, ty: &TField, expr: &str) -> String {
match ty { match ty {
TField::Unit TField::Unit | TField::Array(_) | TField::Set(_) | TField::Map(_, _) => expr.to_owned(),
| TField::Array(_) TField::Ref(_) => {
| TField::Set(_)
| TField::Map(_, _) => expr.to_owned(),
TField::Ref(_) =>
if is_struct { if is_struct {
expr.to_owned() expr.to_owned()
} else { } else {
format!("std::boxed::Box::new({})", expr) format!("std::boxed::Box::new({})", expr)
}, }
}
TField::Base(_) | TField::Any | TField::Embedded => expr.to_owned(), TField::Base(_) | TField::Any | TField::Embedded => expr.to_owned(),
} }
} }
@ -202,8 +281,7 @@ where
for (k, v) in items.into_iter().map(|t| (key(&t), t)) { for (k, v) in items.into_iter().map(|t| (key(&t), t)) {
match current_key.cmp(&Some(k.clone())) { match current_key.cmp(&Some(k.clone())) {
std::cmp::Ordering::Equal => (), std::cmp::Ordering::Equal => (),
std::cmp::Ordering::Less | std::cmp::Ordering::Less | std::cmp::Ordering::Greater => {
std::cmp::Ordering::Greater => {
if let Some(k) = current_key { if let Some(k) = current_key {
result.push((k, std::mem::take(&mut buf))); result.push((k, std::mem::take(&mut buf)));
} }
@ -227,10 +305,12 @@ fn read_expected_literal_seqs(
body: &mut Vec<Item>, body: &mut Vec<Item>,
possibilities: LiteralSeqCases, possibilities: LiteralSeqCases,
) { ) {
let grouped = group_by(possibilities, |(vs, _f)| if vs.is_empty() { let grouped = group_by(possibilities, |(vs, _f)| {
None if vs.is_empty() {
} else { None
Some(vs[0].clone()) } else {
Some(vs[0].clone())
}
}); });
let mut cases = Vec::new(); let mut cases = Vec::new();
let mut nested: LiteralCases = Vec::new(); let mut nested: LiteralCases = Vec::new();
@ -239,16 +319,25 @@ fn read_expected_literal_seqs(
None => { None => {
let mut inner = Vec::new(); let mut inner = Vec::new();
group.into_iter().next().unwrap().1(ctxt, &mut inner); group.into_iter().next().unwrap().1(ctxt, &mut inner);
cases.push(item(seq!["preserves::value::Token::End => ", codeblock(inner)])); cases.push(item(seq![
}, "preserves::value::Token::End => ",
codeblock(inner)
]));
}
Some(h) => { Some(h) => {
let tails = group.into_iter().map(|(mut vs, f)| { let tails = group
vs.remove(0); .into_iter()
(vs, f) .map(|(mut vs, f)| {
}).collect(); vs.remove(0);
nested.push((h, Box::new(|ctxt: &mut FunctionContext, b: &'_ mut Vec<Item>| { (vs, f)
read_expected_literal_seqs(ctxt, b, tails) })
}))); .collect();
nested.push((
h,
Box::new(|ctxt: &mut FunctionContext, b: &'_ mut Vec<Item>| {
read_expected_literal_seqs(ctxt, b, tails)
}),
));
} }
} }
} }
@ -348,7 +437,7 @@ fn simple_pattern_reader(
SimplePattern::Any => { SimplePattern::Any => {
ctxt.define_atom(body, &dest, item("r.demand_next(true)?")); ctxt.define_atom(body, &dest, item("r.demand_next(true)?"));
dest dest
}, }
SimplePattern::Atom { atom_kind: k } => { SimplePattern::Atom { atom_kind: k } => {
let reader = match &**k { let reader = match &**k {
AtomKind::Boolean => "r.next_boolean()?", AtomKind::Boolean => "r.next_boolean()?",
@ -361,54 +450,74 @@ fn simple_pattern_reader(
}; };
ctxt.define_atom(body, &dest, item(reader.to_owned())); ctxt.define_atom(body, &dest, item(reader.to_owned()));
dest dest
}, }
SimplePattern::Embedded { .. } => { SimplePattern::Embedded { .. } => {
ctxt.define_atom(body, &dest, item("r.demand_next(true)?.value().to_embedded()?.clone()")); ctxt.define_atom(
body,
&dest,
item("r.demand_next(true)?.value().to_embedded()?.clone()"),
);
dest dest
}, }
SimplePattern::Lit { value } => { SimplePattern::Lit { value } => {
let f = Box::new(|_ctxt: &mut FunctionContext, _: &'_ mut Vec<Item>| ()); let f = Box::new(|_ctxt: &mut FunctionContext, _: &'_ mut Vec<Item>| ());
read_expected_literals(ctxt, body, vec![(value.clone(), f)]); read_expected_literals(ctxt, body, vec![(value.clone(), f)]);
ctxt.define_atom(body, &dest, item("()")); ctxt.define_atom(body, &dest, item("()"));
dest dest
}, }
SimplePattern::Seqof { pattern } => { SimplePattern::Seqof { pattern } => {
let compound_dest = ctxt.gentempname(); let compound_dest = ctxt.gentempname();
ctxt.with_definite_mode(|ctxt| { ctxt.with_definite_mode(|ctxt| {
let boundary_tracker = BoundaryTracker::unwrap( let boundary_tracker =
ctxt, body, "r.open_sequence()?;", boundary_tracker); BoundaryTracker::unwrap(ctxt, body, "r.open_sequence()?;", boundary_tracker);
let mut inner = Vec::new(); let mut inner = Vec::new();
boundary_tracker.emit_boundary(&mut inner); boundary_tracker.emit_boundary(&mut inner);
let item_dest = simple_pattern_reader(ctxt, pattern, None, &mut inner); let item_dest = simple_pattern_reader(ctxt, pattern, None, &mut inner);
inner.push(item(seq![compound_dest.to_owned(), ".push(", inner.push(item(seq![
store_wrap(true, &field_type(pattern), &item_dest), ");"])); compound_dest.to_owned(),
".push(",
store_wrap(true, &field_type(pattern), &item_dest),
");"
]));
ctxt.declare_compound(body, &compound_dest, item("std::vec::Vec::new()")); ctxt.declare_compound(body, &compound_dest, item("std::vec::Vec::new()"));
boundary_tracker.emit_loop(body, inner); boundary_tracker.emit_loop(body, inner);
}); });
ctxt.define_atom(body, &dest, item(compound_dest)); ctxt.define_atom(body, &dest, item(compound_dest));
dest dest
}, }
SimplePattern::Setof { pattern } => { SimplePattern::Setof { pattern } => {
let compound_dest = ctxt.gentempname(); let compound_dest = ctxt.gentempname();
ctxt.with_definite_mode(|ctxt| { ctxt.with_definite_mode(|ctxt| {
let boundary_tracker = BoundaryTracker::new( let boundary_tracker = BoundaryTracker::new(
ctxt, body, "r.open_set()?;", "_support::B::Item::SetValue"); ctxt,
body,
"r.open_set()?;",
"_support::B::Item::SetValue",
);
let mut inner = Vec::new(); let mut inner = Vec::new();
boundary_tracker.emit_boundary(&mut inner); boundary_tracker.emit_boundary(&mut inner);
let item_dest = simple_pattern_reader(ctxt, pattern, None, &mut inner); let item_dest = simple_pattern_reader(ctxt, pattern, None, &mut inner);
inner.push(item(seq![compound_dest.to_owned(), ".insert(", inner.push(item(seq![
store_wrap(true, &field_type(pattern), &item_dest), ");"])); compound_dest.to_owned(),
".insert(",
store_wrap(true, &field_type(pattern), &item_dest),
");"
]));
ctxt.declare_compound(body, &compound_dest, item("preserves::value::Set::new()")); ctxt.declare_compound(body, &compound_dest, item("preserves::value::Set::new()"));
boundary_tracker.emit_loop(body, inner); boundary_tracker.emit_loop(body, inner);
}); });
ctxt.define_atom(body, &dest, item(compound_dest)); ctxt.define_atom(body, &dest, item(compound_dest));
dest dest
}, }
SimplePattern::Dictof { key, value } => { SimplePattern::Dictof { key, value } => {
let compound_dest = ctxt.gentempname(); let compound_dest = ctxt.gentempname();
ctxt.with_definite_mode(|ctxt| { ctxt.with_definite_mode(|ctxt| {
let mut boundary_tracker = BoundaryTracker::new( let mut boundary_tracker = BoundaryTracker::new(
ctxt, body, "r.open_dictionary()?;", "_support::B::Item::DictionaryKey"); ctxt,
body,
"r.open_dictionary()?;",
"_support::B::Item::DictionaryKey",
);
let mut inner = Vec::new(); let mut inner = Vec::new();
boundary_tracker.emit_boundary(&mut inner); boundary_tracker.emit_boundary(&mut inner);
let key_dest = simple_pattern_reader(ctxt, key, None, &mut inner); let key_dest = simple_pattern_reader(ctxt, key, None, &mut inner);
@ -416,21 +525,25 @@ fn simple_pattern_reader(
boundary_tracker.emit_boundary(&mut inner); boundary_tracker.emit_boundary(&mut inner);
let value_dest = simple_pattern_reader(ctxt, value, None, &mut inner); let value_dest = simple_pattern_reader(ctxt, value, None, &mut inner);
inner.push(item(seq![ inner.push(item(seq![
compound_dest.to_owned(), ".insert(", compound_dest.to_owned(),
store_wrap(true, &field_type(key), &key_dest), ", ", ".insert(",
store_wrap(true, &field_type(value), &value_dest), ");"])); store_wrap(true, &field_type(key), &key_dest),
", ",
store_wrap(true, &field_type(value), &value_dest),
");"
]));
ctxt.declare_compound(body, &compound_dest, item("preserves::value::Map::new()")); ctxt.declare_compound(body, &compound_dest, item("preserves::value::Map::new()"));
boundary_tracker.item_expr = "_support::B::Item::DictionaryKey"; boundary_tracker.item_expr = "_support::B::Item::DictionaryKey";
boundary_tracker.emit_loop(body, inner); boundary_tracker.emit_loop(body, inner);
}); });
ctxt.define_atom(body, &dest, item(compound_dest)); ctxt.define_atom(body, &dest, item(compound_dest));
dest dest
}, }
SimplePattern::Ref(r) => { SimplePattern::Ref(r) => {
let tf = name![ctxt.m.render_ref(&**r, RefRenderStyle::Bare), "deserialize"]; let tf = name![ctxt.m.render_ref(&**r, RefRenderStyle::Bare), "deserialize"];
ctxt.define_atom(body, &dest, item(seq![tf, "(r)?"])); ctxt.define_atom(body, &dest, item(seq![tf, "(r)?"]));
dest dest
}, }
} }
} }
@ -443,9 +556,9 @@ fn named_pattern_reader(
match p { match p {
NamedPattern::Anonymous(p) => { NamedPattern::Anonymous(p) => {
pattern_reader(ctxt, p, boundary_tracker, body); pattern_reader(ctxt, p, boundary_tracker, body);
}, }
NamedPattern::Named(b) => { NamedPattern::Named(b) => {
let Binding { name, pattern} = &**b; let Binding { name, pattern } = &**b;
let dest = simple_pattern_reader(ctxt, pattern, boundary_tracker, body); let dest = simple_pattern_reader(ctxt, pattern, boundary_tracker, body);
let capture_ty = field_type(pattern); let capture_ty = field_type(pattern);
ctxt.capture(names::render_fieldname(name), capture_ty, dest); ctxt.capture(names::render_fieldname(name), capture_ty, dest);
@ -460,41 +573,61 @@ fn pattern_reader(
body: &mut Vec<Item>, body: &mut Vec<Item>,
) -> Option<String> { ) -> Option<String> {
match p { match p {
Pattern::SimplePattern(s) => Pattern::SimplePattern(s) => Some(simple_pattern_reader(ctxt, s, boundary_tracker, body)),
Some(simple_pattern_reader(ctxt, s, boundary_tracker, body)),
Pattern::CompoundPattern(c) => { Pattern::CompoundPattern(c) => {
match &**c { match &**c {
CompoundPattern::Rec { label, fields } => { CompoundPattern::Rec { label, fields } => {
let mut boundary_tracker = BoundaryTracker::new( let mut boundary_tracker = BoundaryTracker::new(
ctxt, body, "r.open_record(None)?;", "_support::B::Item::RecordLabel"); ctxt,
body,
"r.open_record(None)?;",
"_support::B::Item::RecordLabel",
);
boundary_tracker.emit_boundary(body); boundary_tracker.emit_boundary(body);
boundary_tracker.item_expr = "_support::B::Item::RecordField"; boundary_tracker.item_expr = "_support::B::Item::RecordField";
named_pattern_reader(ctxt, &**label, None, body); named_pattern_reader(ctxt, &**label, None, body);
named_pattern_reader(ctxt, &**fields, Some(&boundary_tracker), body); named_pattern_reader(ctxt, &**fields, Some(&boundary_tracker), body);
}, }
CompoundPattern::Tuple { patterns } => { CompoundPattern::Tuple { patterns } => {
let boundary_tracker = BoundaryTracker::unwrap( let boundary_tracker = BoundaryTracker::unwrap(
ctxt, body, "r.open_sequence()?;", boundary_tracker); ctxt,
body,
"r.open_sequence()?;",
boundary_tracker,
);
for p in patterns { for p in patterns {
boundary_tracker.emit_boundary(body); boundary_tracker.emit_boundary(body);
named_pattern_reader(ctxt, p, None, body); named_pattern_reader(ctxt, p, None, body);
} }
body.push(item(seq!["r.ensure_complete", parens![ body.push(item(seq![
boundary_tracker.tracker_name.clone(), "r.ensure_complete",
seq!["&", boundary_tracker.item_expr]], "?;"])); parens![
}, boundary_tracker.tracker_name.clone(),
seq!["&", boundary_tracker.item_expr]
],
"?;"
]));
}
CompoundPattern::TuplePrefix { fixed, variable } => { CompoundPattern::TuplePrefix { fixed, variable } => {
let boundary_tracker = BoundaryTracker::unwrap( let boundary_tracker = BoundaryTracker::unwrap(
ctxt, body, "r.open_sequence()?;", boundary_tracker); ctxt,
body,
"r.open_sequence()?;",
boundary_tracker,
);
for p in fixed { for p in fixed {
boundary_tracker.emit_boundary(body); boundary_tracker.emit_boundary(body);
named_pattern_reader(ctxt, p, None, body); named_pattern_reader(ctxt, p, None, body);
} }
named_pattern_reader(ctxt, &promote(variable), Some(&boundary_tracker), body); named_pattern_reader(ctxt, &promote(variable), Some(&boundary_tracker), body);
}, }
CompoundPattern::Dict { entries } => { CompoundPattern::Dict { entries } => {
let boundary_tracker = BoundaryTracker::new( let boundary_tracker = BoundaryTracker::new(
ctxt, body, "r.open_dictionary()?;", "_support::B::Item::DictionaryKey"); ctxt,
body,
"r.open_dictionary()?;",
"_support::B::Item::DictionaryKey",
);
let mut inner = Vec::new(); let mut inner = Vec::new();
boundary_tracker.emit_boundary(&mut inner); boundary_tracker.emit_boundary(&mut inner);
let mut val_boundary_tracker = boundary_tracker.clone(); let mut val_boundary_tracker = boundary_tracker.clone();
@ -516,6 +649,6 @@ fn pattern_reader(
} }
} }
None None
}, }
} }
} }

View File

@ -1,7 +1,7 @@
use crate::*;
use crate::syntax::block::{Item, Emittable};
use crate::syntax::block::constructors::*;
use crate::gen::schema::*; use crate::gen::schema::*;
use crate::syntax::block::constructors::*;
use crate::syntax::block::{Emittable, Item};
use crate::*;
use preserves::value::Set; use preserves::value::Set;
@ -26,8 +26,8 @@ pub struct TDefinition {
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum TDefinitionBody { pub enum TDefinitionBody {
Union(Vec<(String, TSimple)>), Union(Vec<(String, TSimple)>),
Simple(TSimple), Simple(TSimple),
} }
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
@ -57,11 +57,18 @@ pub struct TypePlugin;
impl compiler::Plugin for TypePlugin { impl compiler::Plugin for TypePlugin {
fn generate_module(&self, m: &mut ModuleContext) { fn generate_module(&self, m: &mut ModuleContext) {
if let EmbeddedTypeName::Ref(r) = &m.schema.embedded_type { if let EmbeddedTypeName::Ref(r) = &m.schema.embedded_type {
m.define_type(item(vertical(false, seq![ m.define_type(item(vertical(
seq!["pub type _Dom = ", m.render_ref(&*r, RefRenderStyle::Bare), ";"], false,
seq!["pub type _Ptr = std::sync::Arc<_Dom>;"], seq![
seq!["pub type _Any = preserves::value::ArcValue<_Ptr>;"] 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>;"]
],
)));
} }
} }
@ -70,24 +77,42 @@ impl compiler::Plugin for TypePlugin {
let ty = definition_type(&m.module_path, Purpose::Codegen, n, d); let ty = definition_type(&m.module_path, Purpose::Codegen, n, d);
m.define_type(item(ty.render(m, n))); m.define_type(item(ty.render(m, n)));
m.define_type(item(seq![ m.define_type(item(seq![
"impl", ty.generic_decl(m), " preserves::value::Domain for ", "impl",
names::render_constructor(n), ty.generic_arg(m), " {}"])); ty.generic_decl(m),
" preserves::value::Domain for ",
names::render_constructor(n),
ty.generic_arg(m),
" {}"
]));
} }
} }
} }
pub fn definition_type(module: &ModulePath, purpose: Purpose, n: &str, d: &Definition) -> TDefinition { pub fn definition_type(
module: &ModulePath,
purpose: Purpose,
n: &str,
d: &Definition,
) -> TDefinition {
TDefinition { TDefinition {
purpose, purpose,
self_ref: Ref { module: module.clone(), name: n.to_owned() }, self_ref: Ref {
module: module.clone(),
name: n.to_owned(),
},
body: match d { body: match d {
Definition::Or { pattern_0, pattern_1, pattern_n } => Definition::Or {
TDefinitionBody::Union(or_definition_type(pattern_0, pattern_1, pattern_n)), pattern_0,
Definition::And { pattern_0, pattern_1, pattern_n } => pattern_1,
TDefinitionBody::Simple(and_definition_type(pattern_0, pattern_1, pattern_n)), pattern_n,
Definition::Pattern(p) => } => TDefinitionBody::Union(or_definition_type(pattern_0, pattern_1, pattern_n)),
TDefinitionBody::Simple(pattern_type(p)), 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)),
},
} }
} }
@ -117,10 +142,10 @@ pub fn and_definition_type(
pub fn pattern_type(p: &Pattern) -> TSimple { pub fn pattern_type(p: &Pattern) -> TSimple {
match p { match p {
Pattern::SimplePattern(p) => Pattern::SimplePattern(p) => TSimple::Field(field_type(p)),
TSimple::Field(field_type(p)), Pattern::CompoundPattern(_) => {
Pattern::CompoundPattern(_) => record_type(&vec![&NamedPattern::Anonymous(Box::new(p.clone()))])
record_type(&vec![&NamedPattern::Anonymous(Box::new(p.clone()))]), }
} }
} }
@ -133,8 +158,10 @@ pub fn record_type(ps: &Vec<&NamedPattern>) -> TSimple {
} }
} }
pub fn gather_fields(ps: &Vec<&NamedPattern>, mut fs: Vec<(String, TField)>) -> Vec<(String, TField)> pub fn gather_fields(
{ ps: &Vec<&NamedPattern>,
mut fs: Vec<(String, TField)>,
) -> Vec<(String, TField)> {
for p in ps.iter() { for p in ps.iter() {
fs = gather_field(p, fs); fs = gather_field(p, fs);
} }
@ -147,31 +174,36 @@ pub fn gather_field(p: &NamedPattern, mut fs: Vec<(String, TField)>) -> Vec<(Str
let Binding { name, pattern } = &**b; let Binding { name, pattern } = &**b;
fs.push((name.to_owned(), field_type(pattern))); fs.push((name.to_owned(), field_type(pattern)));
fs fs
}, }
NamedPattern::Anonymous(p) => match &**p { NamedPattern::Anonymous(p) => match &**p {
Pattern::SimplePattern(_) => Pattern::SimplePattern(_) => fs,
fs,
Pattern::CompoundPattern(c) => match &**c { Pattern::CompoundPattern(c) => match &**c {
CompoundPattern::Rec { label, fields } => CompoundPattern::Rec { label, fields } => {
gather_field(&*fields, gather_field(&*label, fs)), gather_field(&*fields, gather_field(&*label, fs))
CompoundPattern::Tuple { patterns } => }
gather_fields(&patterns.iter().collect(), fs), CompoundPattern::Tuple { patterns } => {
CompoundPattern::TuplePrefix { fixed, variable } => gather_fields(&patterns.iter().collect(), fs)
gather_field(&promote(&**variable), gather_fields(&fixed.iter().collect(), fs)), }
CompoundPattern::TuplePrefix { fixed, variable } => gather_field(
&promote(&**variable),
gather_fields(&fixed.iter().collect(), fs),
),
CompoundPattern::Dict { entries } => { CompoundPattern::Dict { entries } => {
for (_k, p) in &entries.0 { for (_k, p) in &entries.0 {
fs = gather_field(&promote(&p), fs); fs = gather_field(&promote(&p), fs);
} }
fs fs
} }
} },
} },
} }
} }
pub fn promote(p: &NamedSimplePattern) -> NamedPattern { pub fn promote(p: &NamedSimplePattern) -> NamedPattern {
match p { match p {
NamedSimplePattern::Anonymous(p) => NamedPattern::Anonymous(Box::new(Pattern::SimplePattern(p.clone()))), NamedSimplePattern::Anonymous(p) => {
NamedPattern::Anonymous(Box::new(Pattern::SimplePattern(p.clone())))
}
NamedSimplePattern::Named(n) => NamedPattern::Named(n.clone()), NamedSimplePattern::Named(n) => NamedPattern::Named(n.clone()),
} }
} }
@ -179,22 +211,24 @@ pub fn promote(p: &NamedSimplePattern) -> NamedPattern {
pub fn field_type(p: &SimplePattern) -> TField { pub fn field_type(p: &SimplePattern) -> TField {
match p { match p {
SimplePattern::Any => TField::Any, SimplePattern::Any => TField::Any,
SimplePattern::Atom { atom_kind: k } => SimplePattern::Atom { atom_kind: k } => match **k {
match **k { AtomKind::Boolean => TField::Base("bool".to_owned()),
AtomKind::Boolean => TField::Base("bool".to_owned()), AtomKind::Float => TField::Base("preserves::value::Float".to_owned()),
AtomKind::Float => TField::Base("preserves::value::Float".to_owned()), AtomKind::Double => TField::Base("preserves::value::Double".to_owned()),
AtomKind::Double => TField::Base("preserves::value::Double".to_owned()), AtomKind::SignedInteger => {
AtomKind::SignedInteger => TField::Base("preserves::value::signed_integer::SignedInteger".to_owned()), TField::Base("preserves::value::signed_integer::SignedInteger".to_owned())
AtomKind::String => TField::Base("std::string::String".to_owned()), }
AtomKind::ByteString => TField::Base("std::vec::Vec<u8>".to_owned()), AtomKind::String => TField::Base("std::string::String".to_owned()),
AtomKind::Symbol => TField::Base("std::string::String".to_owned()), AtomKind::ByteString => TField::Base("std::vec::Vec<u8>".to_owned()),
}, AtomKind::Symbol => TField::Base("std::string::String".to_owned()),
},
SimplePattern::Embedded { .. } => TField::Embedded, SimplePattern::Embedded { .. } => TField::Embedded,
SimplePattern::Lit { .. } => TField::Unit, SimplePattern::Lit { .. } => TField::Unit,
SimplePattern::Seqof { pattern: t } => TField::Array(Box::new(field_type(t))), SimplePattern::Seqof { pattern: t } => TField::Array(Box::new(field_type(t))),
SimplePattern::Setof { pattern: t } => TField::Set(Box::new(field_type(t))), SimplePattern::Setof { pattern: t } => TField::Set(Box::new(field_type(t))),
SimplePattern::Dictof { key: k, value: v } => SimplePattern::Dictof { key: k, value: v } => {
TField::Map(Box::new(field_type(k)), Box::new(field_type(v))), TField::Map(Box::new(field_type(k)), Box::new(field_type(v)))
}
SimplePattern::Ref(r) => TField::Ref((**r).clone()), SimplePattern::Ref(r) => TField::Ref((**r).clone()),
} }
} }
@ -209,16 +243,20 @@ impl TField {
TField::Embedded => seq![ctxt.any_type(), "::Embedded"], TField::Embedded => seq![ctxt.any_type(), "::Embedded"],
TField::Array(t) => seq!["std::vec::Vec<", t.render(ctxt, false), ">"], TField::Array(t) => seq!["std::vec::Vec<", t.render(ctxt, false), ">"],
TField::Set(t) => seq!["preserves::value::Set<", t.render(ctxt, false), ">"], TField::Set(t) => seq!["preserves::value::Set<", t.render(ctxt, false), ">"],
TField::Map(k, v) => seq!["preserves::value::Map", TField::Map(k, v) => seq![
anglebrackets![k.render(ctxt, false), "preserves::value::Map",
v.render(ctxt, false)]], anglebrackets![k.render(ctxt, false), v.render(ctxt, false)]
TField::Ref(r) => ],
TField::Ref(r) => {
if box_needed { if box_needed {
seq!["std::boxed::Box", anglebrackets![ seq![
ctxt.render_ref(r, RefRenderStyle::Qualified)]] "std::boxed::Box",
anglebrackets![ctxt.render_ref(r, RefRenderStyle::Qualified)]
]
} else { } else {
seq![ctxt.render_ref(r, RefRenderStyle::Qualified)] seq![ctxt.render_ref(r, RefRenderStyle::Qualified)]
}, }
}
TField::Base(n) => seq![n.to_owned()], TField::Base(n) => seq![n.to_owned()],
} }
} }
@ -232,21 +270,26 @@ impl TField {
k.language_types(s, ts); k.language_types(s, ts);
v.language_types(s, ts); v.language_types(s, ts);
} }
TField::Ref(r) => TField::Ref(r) => s.cycle_check(
s.cycle_check( r,
r, |ctxt, r| ctxt.type_for_name(r),
|ctxt, r| ctxt.type_for_name(r), |s, t| match t {
|s, t| match t { Some(ty) if ty.purpose == Purpose::Codegen => ty._language_types(s, ts),
Some(ty) if ty.purpose == Purpose::Codegen => ty._language_types(s, ts), Some(_) | None => {
Some(_) | None => { let xmts = &s
let xmts = &s.context.config.external_modules.get(&r.module.0).unwrap() .context
.rust_language_types; .config
if let Some(f) = xmts.definitions.get(&r.name).or(xmts.fallback.as_ref()) { .external_modules
ts.extend(f(s.context.any_type())); .get(&r.module.0)
} .unwrap()
.rust_language_types;
if let Some(f) = xmts.definitions.get(&r.name).or(xmts.fallback.as_ref()) {
ts.extend(f(s.context.any_type()));
} }
}, }
|| ()), },
|| (),
),
} }
} }
@ -258,29 +301,53 @@ impl TField {
TField::Set(f) => f.has_embedded(s), TField::Set(f) => f.has_embedded(s),
TField::Map(k, v) => k.has_embedded(s) || v.has_embedded(s), TField::Map(k, v) => k.has_embedded(s) || v.has_embedded(s),
TField::Ref(r) => TField::Ref(r) =>
// v TODO: should the "false" be configurable? cf. ModuleContext::ref_has_embedded. // v TODO: should the "false" be configurable? cf. ModuleContext::ref_has_embedded.
{
s.cycle_check( s.cycle_check(
r, r,
|ctxt, r| ctxt.type_for_name(r), |ctxt, r| ctxt.type_for_name(r),
|s, t| t.map(|t| t._has_embedded(s)).unwrap_or(false), |s, t| t.map(|t| t._has_embedded(s)).unwrap_or(false),
|| false), || false,
)
}
} }
} }
} }
impl TSimple { impl TSimple {
pub fn render(&self, ctxt: &ModuleContext, ptr: Item, is_struct: bool, n: &str) -> impl Emittable { pub fn render(
&self,
ctxt: &ModuleContext,
ptr: Item,
is_struct: bool,
n: &str,
) -> impl Emittable {
let semi = if is_struct { seq![";"] } else { seq![] }; let semi = if is_struct { seq![";"] } else { seq![] };
let ppub = if is_struct { "pub " } else { "" }; let ppub = if is_struct { "pub " } else { "" };
seq![names::render_constructor(n), ptr.to_owned(), seq![
match self { names::render_constructor(n),
TSimple::Record(TRecord(fs)) => seq![" ", vertical(false, braces( ptr.to_owned(),
fs.iter().map(|(n, d)| item( match self {
seq![ppub, names::render_fieldname(n), ": ", d.render(ctxt, !is_struct)] TSimple::Record(TRecord(fs)) => seq![
)).collect()))], " ",
TSimple::Field(TField::Unit) => semi, vertical(
TSimple::Field(t) => seq![parens![seq![ppub, t.render(ctxt, !is_struct)]], semi], false,
}] braces(
fs.iter()
.map(|(n, d)| item(seq![
ppub,
names::render_fieldname(n),
": ",
d.render(ctxt, !is_struct)
]))
.collect()
)
)
],
TSimple::Field(TField::Unit) => semi,
TSimple::Field(t) => seq![parens![seq![ppub, t.render(ctxt, !is_struct)]], semi],
}
]
} }
fn language_types(&self, s: &mut WalkState, ts: &mut Set<String>) { fn language_types(&self, s: &mut WalkState, ts: &mut Set<String>) {
@ -301,8 +368,10 @@ impl TSimple {
impl TDefinition { impl TDefinition {
pub fn generic_decl(&self, ctxt: &ModuleContext) -> Item { pub fn generic_decl(&self, ctxt: &ModuleContext) -> Item {
if self.has_embedded(ctxt.bundle) { if self.has_embedded(ctxt.bundle) {
item(anglebrackets![ item(anglebrackets![seq![
seq![ctxt.any_type(), ": preserves::value::NestedValue"]]) ctxt.any_type(),
": preserves::value::NestedValue"
]])
} else { } else {
item("") item("")
} }
@ -310,12 +379,14 @@ impl TDefinition {
pub fn generic_decl_with_defaults(&self, ctxt: &ModuleContext) -> Item { pub fn generic_decl_with_defaults(&self, ctxt: &ModuleContext) -> Item {
if self.has_embedded(ctxt.bundle) { if self.has_embedded(ctxt.bundle) {
item(anglebrackets![ item(anglebrackets![seq![
seq![ctxt.any_type(), ": preserves::value::NestedValue = ", ctxt.any_type(),
match ctxt.schema.embedded_type { ": preserves::value::NestedValue = ",
EmbeddedTypeName::False => "preserves::value::IOValue", match ctxt.schema.embedded_type {
EmbeddedTypeName::Ref(_) => "_Any", EmbeddedTypeName::False => "preserves::value::IOValue",
}]]) EmbeddedTypeName::Ref(_) => "_Any",
}
]])
} else { } else {
item("") item("")
} }
@ -330,17 +401,33 @@ impl TDefinition {
} }
pub fn render(&self, ctxt: &ModuleContext, n: &str) -> impl Emittable { pub fn render(&self, ctxt: &ModuleContext, n: &str) -> impl Emittable {
vertical(false, seq![ vertical(
"#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash)]", false,
match &self.body { seq![
TDefinitionBody::Union(items) => "#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash)]",
seq!["pub enum ", match &self.body {
names::render_constructor(n), self.generic_decl_with_defaults(ctxt), " ", TDefinitionBody::Union(items) => seq![
vertical(false, braces(items.iter().map( "pub enum ",
|(n, d)| item(d.render(ctxt, item(""), false, n))).collect()))], names::render_constructor(n),
TDefinitionBody::Simple(s) => self.generic_decl_with_defaults(ctxt),
seq!["pub struct ", s.render(ctxt, self.generic_decl_with_defaults(ctxt), true, n)], " ",
}]) vertical(
false,
braces(
items
.iter()
.map(|(n, d)| item(d.render(ctxt, item(""), false, n)))
.collect()
)
)
],
TDefinitionBody::Simple(s) => seq![
"pub struct ",
s.render(ctxt, self.generic_decl_with_defaults(ctxt), true, n)
],
}
],
)
} }
fn walk_state<'a, 'b>(&self, ctxt: &'a BundleContext<'b>) -> WalkState<'a, 'b> { fn walk_state<'a, 'b>(&self, ctxt: &'a BundleContext<'b>) -> WalkState<'a, 'b> {
@ -355,7 +442,9 @@ impl TDefinition {
fn _language_types(&self, s: &mut WalkState, ts: &mut Set<String>) { fn _language_types(&self, s: &mut WalkState, ts: &mut Set<String>) {
match &self.body { match &self.body {
TDefinitionBody::Union(entries) => entries.iter().for_each(|(_k, v)| v.language_types(s, ts)), TDefinitionBody::Union(entries) => {
entries.iter().for_each(|(_k, v)| v.language_types(s, ts))
}
TDefinitionBody::Simple(t) => t.language_types(s, ts), TDefinitionBody::Simple(t) => t.language_types(s, ts),
} }
} }

View File

@ -1,12 +1,12 @@
use crate::*;
use crate::gen::schema::*; use crate::gen::schema::*;
use crate::syntax::block::constructors::*; use crate::syntax::block::constructors::*;
use crate::syntax::block::{Emittable, Item, escape_string}; use crate::syntax::block::{escape_string, Emittable, Item};
use crate::*;
use std::cell::Cell; use std::cell::Cell;
use std::rc::Rc; use std::rc::Rc;
use super::context::{ModuleContextMode, ModuleContext, FunctionContext}; use super::context::{FunctionContext, ModuleContext, ModuleContextMode};
use super::names; use super::names;
use super::types::*; use super::types::*;
@ -14,7 +14,12 @@ use super::types::*;
pub struct UnparserPlugin; pub struct UnparserPlugin;
impl compiler::Plugin for UnparserPlugin { impl compiler::Plugin for UnparserPlugin {
fn generate_definition(&self, module_ctxt: &mut ModuleContext, definition_name: &str, definition: &Definition) { fn generate_definition(
&self,
module_ctxt: &mut ModuleContext,
definition_name: &str,
definition: &Definition,
) {
if let ModuleContextMode::TargetGeneric = module_ctxt.mode { if let ModuleContextMode::TargetGeneric = module_ctxt.mode {
gen_definition_unparser(module_ctxt, definition_name, definition) gen_definition_unparser(module_ctxt, definition_name, definition)
} }
@ -53,58 +58,118 @@ struct ValueContext {
} }
fn normal_none(is_struct: bool) -> ValueContext { fn normal_none(is_struct: bool) -> ValueContext {
ValueContext { src: None, sink: ValueSink::Normal, is_struct } ValueContext {
src: None,
sink: ValueSink::Normal,
is_struct,
}
} }
fn normal_src(src: String, is_struct: bool) -> ValueContext { fn normal_src(src: String, is_struct: bool) -> ValueContext {
ValueContext { src: Some(src), sink: ValueSink::Normal, is_struct } ValueContext {
src: Some(src),
sink: ValueSink::Normal,
is_struct,
}
} }
pub fn gen_definition_unparser(m: &mut ModuleContext, n: &str, d: &Definition) { pub fn gen_definition_unparser(m: &mut ModuleContext, n: &str, d: &Definition) {
let ty = definition_type(&m.module_path, Purpose::Codegen, n, d); let ty = definition_type(&m.module_path, Purpose::Codegen, n, d);
m.define_function( m.define_function(n, |mut ctxt| {
n, let mut body = vec![];
|mut ctxt| {
let mut body = vec![];
match d { match d {
Definition::Or { pattern_0, pattern_1, pattern_n } => { Definition::Or {
let mut ps = vec![&**pattern_0, &**pattern_1]; pattern_0,
ps.extend(pattern_n); pattern_1,
body.push(item(seq!["match self ", codeblock(ps.iter().map( pattern_n,
| NamedAlternative { variant_label: name, pattern: pat } | ctxt.branch(|ctxt| { } => {
let ctorname = item(name![names::render_constructor(n), names::render_constructor(name)]); let mut ps = vec![&**pattern_0, &**pattern_1];
let (patpat, vc) = destruct(ctxt, ctorname, false, &pattern_type(pat)); ps.extend(pattern_n);
item(seq![patpat, " => ", pattern_unparser(ctxt, pat, &vc), ","]) body.push(item(seq![
})).collect())])); "match self ",
} codeblock(
Definition::And { pattern_0, pattern_1, pattern_n } => { ps.iter()
let mut ps = vec![&**pattern_0, &**pattern_1]; .map(
ps.extend(pattern_n); |NamedAlternative {
let (patpat, vc) = destruct(&mut ctxt, item(names::render_constructor(n)), true, &record_type(&ps)); variant_label: name,
body.push(item(seq!["let ", patpat, " = self;"])); pattern: pat,
body.push(item(seq![ }| ctxt.branch(|ctxt| {
"preserves::value::merge(vec!", brackets(ps.iter().map( let ctorname = item(name![
|p| named_pattern_unparser(&mut ctxt, p, &vc)).collect() names::render_constructor(n),
), ").expect", parens![escape_string(&( names::render_constructor(name)
"merge of ".to_owned() + &ctxt.fully_qualified_error_context()))]])); ]);
} let (patpat, vc) =
Definition::Pattern(p) => { destruct(ctxt, ctorname, false, &pattern_type(pat));
let (patpat, vc) = destruct(&mut ctxt, item(names::render_constructor(n)), true, &pattern_type(p)); item(seq![
body.push(item(seq!["let ", patpat, " = self;"])); patpat,
body.push(pattern_unparser(&mut ctxt, p, &vc)); " => ",
} pattern_unparser(ctxt, pat, &vc),
","
])
})
)
.collect()
)
]));
} }
Definition::And {
pattern_0,
pattern_1,
pattern_n,
} => {
let mut ps = vec![&**pattern_0, &**pattern_1];
ps.extend(pattern_n);
let (patpat, vc) = destruct(
&mut ctxt,
item(names::render_constructor(n)),
true,
&record_type(&ps),
);
body.push(item(seq!["let ", patpat, " = self;"]));
body.push(item(seq![
"preserves::value::merge(vec!",
brackets(
ps.iter()
.map(|p| named_pattern_unparser(&mut ctxt, p, &vc))
.collect()
),
").expect",
parens![escape_string(
&("merge of ".to_owned() + &ctxt.fully_qualified_error_context())
)]
]));
}
Definition::Pattern(p) => {
let (patpat, vc) = destruct(
&mut ctxt,
item(names::render_constructor(n)),
true,
&pattern_type(p),
);
body.push(item(seq!["let ", patpat, " = self;"]));
body.push(pattern_unparser(&mut ctxt, p, &vc));
}
}
item(seq!["impl", item(seq![
ctxt.m.parse_unparse_generic_decls(&ty), "impl",
" _support::Unparse", anglebrackets!["_L", ctxt.m.any_type()], " for ", ctxt.m.parse_unparse_generic_decls(&ty),
names::render_constructor(n), ty.generic_arg(ctxt.m), " ", " _support::Unparse",
codeblock![ anglebrackets!["_L", ctxt.m.any_type()],
seq!["fn unparse(&self, _ctxt: _L) -> ", ctxt.m.any_type(), " ", " for ",
codeblock(body)]]]) names::render_constructor(n),
}); ty.generic_arg(ctxt.m),
" ",
codeblock![seq![
"fn unparse(&self, _ctxt: _L) -> ",
ctxt.m.any_type(),
" ",
codeblock(body)
]]
])
});
} }
fn destruct( fn destruct(
@ -117,17 +182,29 @@ fn destruct(
TSimple::Field(TField::Unit) => (seq![ctorname], normal_none(is_struct)), TSimple::Field(TField::Unit) => (seq![ctorname], normal_none(is_struct)),
TSimple::Field(_) => { TSimple::Field(_) => {
let src = ctxt.gentempname(); let src = ctxt.gentempname();
(seq![ctorname, parens![src.to_owned()]], normal_src(src, is_struct)) (
seq![ctorname, parens![src.to_owned()]],
normal_src(src, is_struct),
)
} }
TSimple::Record(TRecord(fs)) => { TSimple::Record(TRecord(fs)) => {
for (fname, fty) in fs { for (fname, fty) in fs {
let fsrc = ctxt.gentempname(); let fsrc = ctxt.gentempname();
ctxt.capture(names::render_fieldname(fname), fty.clone(), fsrc); ctxt.capture(names::render_fieldname(fname), fty.clone(), fsrc);
} }
(seq![ (
ctorname, " ", braces(ctxt.captures.iter().map( seq![
|c| item(seq![c.field_name.clone(), ": ", c.source_expr.clone()])).collect())], ctorname,
normal_none(is_struct)) " ",
braces(
ctxt.captures
.iter()
.map(|c| item(seq![c.field_name.clone(), ": ", c.source_expr.clone()]))
.collect()
)
],
normal_none(is_struct),
)
} }
} }
} }
@ -139,97 +216,127 @@ fn simple_pattern_unparser(
) -> Item { ) -> Item {
let src = &vc.src; let src = &vc.src;
match p { match p {
SimplePattern::Any => SimplePattern::Any => item(seq![src.as_ref().unwrap().to_owned(), ".clone()"]),
item(seq![src.as_ref().unwrap().to_owned(), ".clone()"]), SimplePattern::Atom { atom_kind: k } => match &**k {
SimplePattern::Atom { atom_kind: k } => { AtomKind::Symbol => item(seq![
match &**k { "preserves::value::Value::symbol(",
AtomKind::Symbol => src.as_ref().unwrap().to_owned(),
item(seq!["preserves::value::Value::symbol(", src.as_ref().unwrap().to_owned(), ").wrap()"]), ").wrap()"
AtomKind::ByteString => ]),
item(seq!["preserves::value::Value::ByteString(", src.as_ref().unwrap().to_owned(), ".clone()).wrap()"]), AtomKind::ByteString => item(seq![
_ => "preserves::value::Value::ByteString(",
item(seq!["preserves::value::Value::from(", src.as_ref().unwrap().to_owned(), ").wrap()"]) src.as_ref().unwrap().to_owned(),
} ".clone()).wrap()"
]),
_ => item(seq![
"preserves::value::Value::from(",
src.as_ref().unwrap().to_owned(),
").wrap()"
]),
},
SimplePattern::Embedded { .. } => item(seq![
"preserves::value::Value::Embedded(",
src.as_ref().unwrap().to_owned(),
".clone()).wrap()"
]),
SimplePattern::Lit { value } => {
item(seq![parens![ctxt.m.define_literal(value)], ".clone()"])
} }
SimplePattern::Embedded { .. } =>
item(seq!["preserves::value::Value::Embedded(", src.as_ref().unwrap().to_owned(), ".clone()).wrap()"]),
SimplePattern::Lit { value } =>
item(seq![parens![ctxt.m.define_literal(value)], ".clone()"]),
SimplePattern::Seqof { pattern } => { SimplePattern::Seqof { pattern } => {
let mut fields_sink = sequenceify(ctxt, vc); let mut fields_sink = sequenceify(ctxt, vc);
let tmp = ctxt.gentempname(); let tmp = ctxt.gentempname();
fields_sink.body.push(item(seq![ fields_sink.body.push(item(seq![
"for ", tmp.to_owned(), " in ", "for ",
src.as_ref().unwrap().to_owned(), " ", codeblock![ tmp.to_owned(),
seq![fields_sink.vec_expr.clone(), ".push(", " in ",
simple_pattern_unparser(ctxt, src.as_ref().unwrap().to_owned(),
pattern, " ",
&normal_src(tmp, true)), ");"]]])); codeblock![seq![
fields_sink.vec_expr.clone(),
".push(",
simple_pattern_unparser(ctxt, pattern, &normal_src(tmp, true)),
");"
]]
]));
finish(fields_sink) finish(fields_sink)
} }
SimplePattern::Setof { pattern } => { SimplePattern::Setof { pattern } => {
let tmp = ctxt.gentempname(); let tmp = ctxt.gentempname();
item(seq!["preserves::value::Value::Set(", item(seq![
src.as_ref().unwrap().to_owned(), ".iter().map(|", tmp.to_owned(), "| ", "preserves::value::Value::Set(",
simple_pattern_unparser(ctxt, pattern, &normal_src(tmp, true)), src.as_ref().unwrap().to_owned(),
").collect()).wrap()"]) ".iter().map(|",
tmp.to_owned(),
"| ",
simple_pattern_unparser(ctxt, pattern, &normal_src(tmp, true)),
").collect()).wrap()"
])
} }
SimplePattern::Dictof { key, value } => { SimplePattern::Dictof { key, value } => {
let tmp_key = ctxt.gentempname(); let tmp_key = ctxt.gentempname();
let tmp_value = ctxt.gentempname(); let tmp_value = ctxt.gentempname();
item(seq!["preserves::value::Value::Dictionary(", item(seq![
src.as_ref().unwrap().to_owned(), "preserves::value::Value::Dictionary(",
".iter().map(|(", tmp_key.to_owned(), ", ", tmp_value.to_owned(), ")| ", src.as_ref().unwrap().to_owned(),
parens![simple_pattern_unparser(ctxt, key, &normal_src(tmp_key, true)), ".iter().map(|(",
simple_pattern_unparser(ctxt, value, &normal_src(tmp_value, true))], tmp_key.to_owned(),
").collect()).wrap()"]) ", ",
tmp_value.to_owned(),
")| ",
parens![
simple_pattern_unparser(ctxt, key, &normal_src(tmp_key, true)),
simple_pattern_unparser(ctxt, value, &normal_src(tmp_value, true))
],
").collect()).wrap()"
])
} }
SimplePattern::Ref(_r) => SimplePattern::Ref(_r) => item(seq![
item(seq![src.as_ref().unwrap().to_owned(), src.as_ref().unwrap().to_owned(),
if vc.is_struct { "" } else { ".as_ref()" }, if vc.is_struct { "" } else { ".as_ref()" },
".unparse(_ctxt)"]), ".unparse(_ctxt)"
]),
} }
} }
fn named_pattern_unparser( fn named_pattern_unparser(ctxt: &mut FunctionContext, p: &NamedPattern, vc: &ValueContext) -> Item {
ctxt: &mut FunctionContext,
p: &NamedPattern,
vc: &ValueContext,
) -> Item {
match p { match p {
NamedPattern::Anonymous(p) => NamedPattern::Anonymous(p) => pattern_unparser(ctxt, p, vc),
pattern_unparser(ctxt, p, vc),
NamedPattern::Named(b) => { NamedPattern::Named(b) => {
let Binding { name, pattern} = &**b; let Binding { name, pattern } = &**b;
let src = ctxt.lookup_capture(&names::render_fieldname(name)).source_expr.to_owned(); let src = ctxt
simple_pattern_unparser(ctxt, pattern, &ValueContext { .lookup_capture(&names::render_fieldname(name))
src: Some(src), .source_expr
sink: vc.sink.clone(), .to_owned();
is_struct: vc.is_struct, simple_pattern_unparser(
}) ctxt,
pattern,
&ValueContext {
src: Some(src),
sink: vc.sink.clone(),
is_struct: vc.is_struct,
},
)
} }
} }
} }
fn pattern_unparser( fn pattern_unparser(ctxt: &mut FunctionContext, p: &Pattern, vc: &ValueContext) -> Item {
ctxt: &mut FunctionContext,
p: &Pattern,
vc: &ValueContext,
) -> Item {
match p { match p {
Pattern::SimplePattern(s) => Pattern::SimplePattern(s) => simple_pattern_unparser(ctxt, s, vc),
simple_pattern_unparser(ctxt, s, vc), Pattern::CompoundPattern(c) => match &**c {
Pattern::CompoundPattern(c) => { CompoundPattern::Rec { label, fields } => {
match &**c { let rtmp = ctxt.gentempname();
CompoundPattern::Rec { label, fields } => { let mut body = Vec::new();
let rtmp = ctxt.gentempname(); let init_expr = item(seq![
let mut body = Vec::new(); "preserves::value::Record(vec![",
let init_expr = item(seq![ named_pattern_unparser(ctxt, label, &normal_none(vc.is_struct)),
"preserves::value::Record(vec![", "])"
named_pattern_unparser(ctxt, label, &normal_none(vc.is_struct)), ]);
"])"]); ctxt.declare_compound(&mut body, &rtmp, init_expr);
ctxt.declare_compound(&mut body, &rtmp, init_expr); named_pattern_unparser(
named_pattern_unparser(ctxt, fields, &ValueContext { ctxt,
fields,
&ValueContext {
src: None, src: None,
sink: ValueSink::Fields(Rc::new(Cell::new(Some(FieldsSink { sink: ValueSink::Fields(Rc::new(Cell::new(Some(FieldsSink {
finish: item(seq![rtmp.clone(), ".finish().wrap()"]), finish: item(seq![rtmp.clone(), ".finish().wrap()"]),
@ -237,53 +344,73 @@ fn pattern_unparser(
body, body,
})))), })))),
is_struct: vc.is_struct, is_struct: vc.is_struct,
}) },
}, )
CompoundPattern::Tuple { patterns } => { }
let mut fields_sink = sequenceify(ctxt, vc); CompoundPattern::Tuple { patterns } => {
fixed_sequence_parser(ctxt, patterns, &mut fields_sink, vc.is_struct); let mut fields_sink = sequenceify(ctxt, vc);
finish(fields_sink) fixed_sequence_parser(ctxt, patterns, &mut fields_sink, vc.is_struct);
}, finish(fields_sink)
CompoundPattern::TuplePrefix { fixed, variable } => { }
let mut fields_sink = sequenceify(ctxt, vc); CompoundPattern::TuplePrefix { fixed, variable } => {
fixed_sequence_parser(ctxt, fixed, &mut fields_sink, vc.is_struct); let mut fields_sink = sequenceify(ctxt, vc);
named_pattern_unparser(ctxt, &promote(variable), &ValueContext { fixed_sequence_parser(ctxt, fixed, &mut fields_sink, vc.is_struct);
named_pattern_unparser(
ctxt,
&promote(variable),
&ValueContext {
src: vc.src.clone(), src: vc.src.clone(),
sink: ValueSink::Fields(Rc::new(Cell::new(Some(fields_sink)))), sink: ValueSink::Fields(Rc::new(Cell::new(Some(fields_sink)))),
is_struct: true, is_struct: true,
}) },
}, )
CompoundPattern::Dict { entries } => { }
let dtmp = ctxt.gentempname(); CompoundPattern::Dict { entries } => {
let mut body = Vec::new(); let dtmp = ctxt.gentempname();
ctxt.declare_compound(&mut body, &dtmp, item("preserves::value::Map::new()")); let mut body = Vec::new();
for (key_lit, value_pat) in entries.0.iter() { ctxt.declare_compound(&mut body, &dtmp, item("preserves::value::Map::new()"));
body.push(item(seq![dtmp.clone(), ".insert", parens![ for (key_lit, value_pat) in entries.0.iter() {
body.push(item(seq![
dtmp.clone(),
".insert",
parens![
seq![parens![ctxt.m.define_literal(key_lit)], ".clone()"], seq![parens![ctxt.m.define_literal(key_lit)], ".clone()"],
named_pattern_unparser(ctxt, &promote(value_pat), &normal_none(vc.is_struct))], ";"])); named_pattern_unparser(
} ctxt,
body.push(item(seq!["preserves::value::Value::Dictionary(", dtmp, ").wrap()"])); &promote(value_pat),
item(codeblock(body)) &normal_none(vc.is_struct)
)
],
";"
]));
} }
body.push(item(seq![
"preserves::value::Value::Dictionary(",
dtmp,
").wrap()"
]));
item(codeblock(body))
} }
}, },
} }
} }
fn sequenceify<'a>( fn sequenceify<'a>(ctxt: &mut FunctionContext, vc: &'a ValueContext) -> FieldsSink {
ctxt: &mut FunctionContext,
vc: &'a ValueContext,
) -> FieldsSink {
match vc { match vc {
ValueContext { sink: ValueSink::Fields(fields_sink), .. } => ValueContext {
(**fields_sink).take().unwrap(), sink: ValueSink::Fields(fields_sink),
..
} => (**fields_sink).take().unwrap(),
_ => { _ => {
let rtmp = ctxt.gentempname(); let rtmp = ctxt.gentempname();
let mut body = Vec::new(); let mut body = Vec::new();
ctxt.declare_compound(&mut body, &rtmp, item("std::vec::Vec::new()")); ctxt.declare_compound(&mut body, &rtmp, item("std::vec::Vec::new()"));
FieldsSink { FieldsSink {
finish: item(seq![ finish: item(seq![
"preserves::value::Value::Sequence", parens![rtmp.clone()], ".wrap()"]), "preserves::value::Value::Sequence",
parens![rtmp.clone()],
".wrap()"
]),
vec_expr: item(rtmp), vec_expr: item(rtmp),
body, body,
} }
@ -303,7 +430,11 @@ fn fixed_sequence_parser(
is_struct: bool, is_struct: bool,
) { ) {
for p in patterns { for p in patterns {
fields_sink.body.push(item(seq![fields_sink.vec_expr.clone(), ".push", parens![ fields_sink.body.push(item(seq![
named_pattern_unparser(ctxt, p, &normal_none(is_struct))], ";"])); fields_sink.vec_expr.clone(),
".push",
parens![named_pattern_unparser(ctxt, p, &normal_none(is_struct))],
";"
]));
} }
} }

View File

@ -1,7 +1,7 @@
pub mod syntax;
pub mod compiler; pub mod compiler;
pub mod support;
pub mod gen; pub mod gen;
pub mod support;
pub mod syntax;
pub use support::Codec; pub use support::Codec;
pub use support::Deserialize; pub use support::Deserialize;
@ -17,8 +17,8 @@ mod tests {
#[test] #[test]
fn simple_rendering() { fn simple_rendering() {
use crate::*;
use crate::syntax::block::*; use crate::syntax::block::*;
use crate::*;
let code = semiblock![ let code = semiblock![
seq!["f", parens!["a", "b", "c"]], seq!["f", parens!["a", "b", "c"]],
@ -35,10 +35,10 @@ mod tests {
#[test] #[test]
fn metaschema_parsing() -> Result<(), std::io::Error> { fn metaschema_parsing() -> Result<(), std::io::Error> {
use preserves::value::{BinarySource, IOBinarySource, Reader}; use crate::gen::schema::*;
use crate::support::Parse; use crate::support::Parse;
use crate::support::Unparse; use crate::support::Unparse;
use crate::gen::schema::*; use preserves::value::{BinarySource, IOBinarySource, Reader};
let mut f = std::fs::File::open("../../../schema/schema.bin")?; let mut f = std::fs::File::open("../../../schema/schema.bin")?;
let mut src = IOBinarySource::new(&mut f); let mut src = IOBinarySource::new(&mut f);

View File

@ -1,9 +1,9 @@
use crate::gen::schema::*; use crate::gen::schema::*;
use preserves::value::merge::merge2;
use preserves::value::Map; use preserves::value::Map;
use preserves::value::NestedValue; use preserves::value::NestedValue;
use preserves::value::Value; use preserves::value::Value;
use preserves::value::merge::merge2;
pub type Env<V> = Map<Vec<String>, Schema<V>>; pub type Env<V> = Map<Vec<String>, Schema<V>>;
@ -28,7 +28,8 @@ impl<'a, V: NestedValue> Context<'a, V> {
} }
pub fn dynamic_parse(&mut self, module: &Vec<String>, name: &str, v: &V) -> Option<V> { pub fn dynamic_parse(&mut self, module: &Vec<String>, name: &str, v: &V) -> Option<V> {
let old_module = (module.len() > 0).then(|| std::mem::replace(&mut self.module, module.clone())); let old_module =
(module.len() > 0).then(|| std::mem::replace(&mut self.module, module.clone()));
let schema = self.env.get(&self.module); let schema = self.env.get(&self.module);
let definition = schema.and_then(|s| s.definitions.0.get(name)); let definition = schema.and_then(|s| s.definitions.0.get(name));
let result = definition.and_then(|d| d.dynamic_parse(self, v)); let result = definition.and_then(|d| d.dynamic_parse(self, v));
@ -46,17 +47,27 @@ impl<'a, V: NestedValue> Context<'a, V> {
impl<V: NestedValue> Definition<V> { impl<V: NestedValue> Definition<V> {
fn dynamic_parse(&self, ctxt: &mut Context<V>, v: &V) -> Option<V> { fn dynamic_parse(&self, ctxt: &mut Context<V>, v: &V) -> Option<V> {
match self { match self {
Definition::Or { pattern_0, pattern_1, pattern_n } => Definition::Or {
pattern_0.dynamic_parse(ctxt, v) pattern_0,
pattern_1,
pattern_n,
} => pattern_0
.dynamic_parse(ctxt, v)
.or_else(|| pattern_1.dynamic_parse(ctxt, v)) .or_else(|| pattern_1.dynamic_parse(ctxt, v))
.or_else(|| pattern_n.iter().find_map(|p| p.dynamic_parse(ctxt, v))), .or_else(|| pattern_n.iter().find_map(|p| p.dynamic_parse(ctxt, v))),
Definition::And { pattern_0, pattern_1, pattern_n } => Definition::And {
pattern_0.dynamic_parse(ctxt, v) pattern_0,
.and_then(|w0| pattern_1.dynamic_parse(ctxt, v) pattern_1,
.and_then(|w1| pattern_n.iter().fold(merge(w0, w1), |w, p| { pattern_n,
w.and_then(|w| p.dynamic_parse(ctxt, v).and_then( } => pattern_0
|wn| merge(w, wn))) .dynamic_parse(ctxt, v)
}))) .and_then(|w0| {
pattern_1.dynamic_parse(ctxt, v).and_then(|w1| {
pattern_n.iter().fold(merge(w0, w1), |w, p| {
w.and_then(|w| p.dynamic_parse(ctxt, v).and_then(|wn| merge(w, wn)))
})
})
})
.map(|w| DynField::Compound(w).finish()), .map(|w| DynField::Compound(w).finish()),
Definition::Pattern(p) => p.dynamic_parse(ctxt, v).map(|w| w.finish()), Definition::Pattern(p) => p.dynamic_parse(ctxt, v).map(|w| w.finish()),
} }
@ -69,8 +80,10 @@ impl<V: NestedValue> NamedAlternative<V> {
let mut r = Value::simple_record(&self.variant_label, 1); let mut r = Value::simple_record(&self.variant_label, 1);
match w { match w {
DynField::Simple(field) => r.fields_vec_mut().push(field), DynField::Simple(field) => r.fields_vec_mut().push(field),
DynField::Compound(fields) => if fields.len() > 0 { DynField::Compound(fields) => {
r.fields_vec_mut().push(V::new(fields)) if fields.len() > 0 {
r.fields_vec_mut().push(V::new(fields))
}
} }
} }
r.finish().wrap() r.finish().wrap()
@ -83,9 +96,12 @@ impl<V: NestedValue> NamedPattern<V> {
match self { match self {
NamedPattern::Named(b) => { NamedPattern::Named(b) => {
let binding = &**b; let binding = &**b;
binding.pattern.dynamic_parse(ctxt, v).map(|w| w.to_map(Some(&binding.name))) binding
.pattern
.dynamic_parse(ctxt, v)
.map(|w| w.to_map(Some(&binding.name)))
} }
NamedPattern::Anonymous(b) => b.dynamic_parse(ctxt, v).map(|w| w.to_map(None)) NamedPattern::Anonymous(b) => b.dynamic_parse(ctxt, v).map(|w| w.to_map(None)),
} }
} }
} }
@ -95,11 +111,12 @@ impl<V: NestedValue> NamedSimplePattern<V> {
match self { match self {
NamedSimplePattern::Named(b) => { NamedSimplePattern::Named(b) => {
let binding = &**b; let binding = &**b;
binding.pattern.dynamic_parse(ctxt, v).map( binding
|w| DynField::Compound(w.to_map(Some(&binding.name)))) .pattern
.dynamic_parse(ctxt, v)
.map(|w| DynField::Compound(w.to_map(Some(&binding.name))))
} }
NamedSimplePattern::Anonymous(b) => NamedSimplePattern::Anonymous(b) => b.dynamic_parse(ctxt, v),
b.dynamic_parse(ctxt, v),
} }
} }
} }
@ -112,35 +129,57 @@ impl<V: NestedValue> SimplePattern<V> {
AtomKind::Boolean => v.value().is_boolean().then(|| DynField::Simple(v.clone())), AtomKind::Boolean => v.value().is_boolean().then(|| DynField::Simple(v.clone())),
AtomKind::Float => v.value().is_float().then(|| DynField::Simple(v.clone())), AtomKind::Float => v.value().is_float().then(|| DynField::Simple(v.clone())),
AtomKind::Double => v.value().is_double().then(|| DynField::Simple(v.clone())), AtomKind::Double => v.value().is_double().then(|| DynField::Simple(v.clone())),
AtomKind::SignedInteger => v.value().is_signedinteger().then(|| DynField::Simple(v.clone())), AtomKind::SignedInteger => v
.value()
.is_signedinteger()
.then(|| DynField::Simple(v.clone())),
AtomKind::String => v.value().is_string().then(|| DynField::Simple(v.clone())), AtomKind::String => v.value().is_string().then(|| DynField::Simple(v.clone())),
AtomKind::ByteString => v.value().is_bytestring().then(|| DynField::Simple(v.clone())), AtomKind::ByteString => v
.value()
.is_bytestring()
.then(|| DynField::Simple(v.clone())),
AtomKind::Symbol => v.value().is_symbol().then(|| DynField::Simple(v.clone())), AtomKind::Symbol => v.value().is_symbol().then(|| DynField::Simple(v.clone())),
}, },
SimplePattern::Embedded { .. } => v.value().is_embedded().then(|| DynField::Simple(v.clone())), SimplePattern::Embedded { .. } => {
v.value().is_embedded().then(|| DynField::Simple(v.clone()))
}
SimplePattern::Lit { value } => (v == value).then(|| DynField::Compound(Map::new())), SimplePattern::Lit { value } => (v == value).then(|| DynField::Compound(Map::new())),
SimplePattern::Seqof { pattern } => SimplePattern::Seqof { pattern } => v
v.value().as_sequence() .value()
.and_then(|vs| vs.iter().map(|v| (**pattern).dynamic_parse(ctxt, v).map(|w| w.finish())) .as_sequence()
.collect::<Option<Vec<V>>>()) .and_then(|vs| {
vs.iter()
.map(|v| (**pattern).dynamic_parse(ctxt, v).map(|w| w.finish()))
.collect::<Option<Vec<V>>>()
})
.map(|ws| DynField::Simple(V::new(ws))), .map(|ws| DynField::Simple(V::new(ws))),
SimplePattern::Setof { pattern } => SimplePattern::Setof { pattern } => v
v.value().as_set() .value()
.and_then(|vs| vs.iter().map(|v| (**pattern).dynamic_parse(ctxt, v).map(|w| w.finish())) .as_set()
.collect::<Option<Vec<V>>>()) .and_then(|vs| {
vs.iter()
.map(|v| (**pattern).dynamic_parse(ctxt, v).map(|w| w.finish()))
.collect::<Option<Vec<V>>>()
})
.map(|ws| DynField::Simple(V::new(ws))), .map(|ws| DynField::Simple(V::new(ws))),
SimplePattern::Dictof { key, value } => SimplePattern::Dictof { key, value } => v
v.value().as_dictionary() .value()
.as_dictionary()
.and_then(|d| { .and_then(|d| {
d.iter().map(|(k, v)| { d.iter()
(**key).dynamic_parse(ctxt, k) .map(|(k, v)| {
.and_then(|kw| (**value).dynamic_parse(ctxt, v) (**key).dynamic_parse(ctxt, k).and_then(|kw| {
.map(|vw| (kw.finish(), vw.finish()))) (**value)
}).collect::<Option<Map<V, V>>>() .dynamic_parse(ctxt, v)
.map(|vw| (kw.finish(), vw.finish()))
})
})
.collect::<Option<Map<V, V>>>()
}) })
.map(|d| DynField::Simple(V::new(d))), .map(|d| DynField::Simple(V::new(d))),
SimplePattern::Ref(r) => SimplePattern::Ref(r) => ctxt
ctxt.dynamic_parse(&r.module.0, &r.name, v).map(DynField::Simple), .dynamic_parse(&r.module.0, &r.name, v)
.map(DynField::Simple),
} }
} }
} }
@ -148,43 +187,57 @@ impl<V: NestedValue> SimplePattern<V> {
impl<V: NestedValue> CompoundPattern<V> { impl<V: NestedValue> CompoundPattern<V> {
fn dynamic_parse(&self, ctxt: &mut Context<V>, v: &V) -> Option<Map<V, V>> { fn dynamic_parse(&self, ctxt: &mut Context<V>, v: &V) -> Option<Map<V, V>> {
match self { match self {
CompoundPattern::Rec { label, fields } => CompoundPattern::Rec { label, fields } => v.value().as_record(None).and_then(|r| {
v.value().as_record(None).and_then( (**label).dynamic_parse(ctxt, r.label()).and_then(|lw| {
|r| (**label).dynamic_parse(ctxt, r.label()).and_then( (**fields)
|lw| (**fields).dynamic_parse(ctxt, &V::new(r.fields().to_vec())).and_then( .dynamic_parse(ctxt, &V::new(r.fields().to_vec()))
|fsw| merge(lw, fsw)))), .and_then(|fsw| merge(lw, fsw))
CompoundPattern::Tuple { patterns } => })
v.value().as_sequence().and_then( }),
|vs| if vs.len() == patterns.len() { CompoundPattern::Tuple { patterns } => v.value().as_sequence().and_then(|vs| {
patterns.iter().zip(vs) if vs.len() == patterns.len() {
patterns
.iter()
.zip(vs)
.fold(Some(Map::new()), |acc, (p, v)| {
acc.and_then(|acc| p.dynamic_parse(ctxt, v).and_then(|w| merge(acc, w)))
})
} else {
None
}
}),
CompoundPattern::TuplePrefix { fixed, variable } => {
v.value().as_sequence().and_then(|vs| {
if vs.len() >= fixed.len() {
fixed
.iter()
.zip(vs)
.fold(Some(Map::new()), |acc, (p, v)| { .fold(Some(Map::new()), |acc, (p, v)| {
acc.and_then(|acc| p.dynamic_parse(ctxt, v).and_then( acc.and_then(|acc| {
|w| merge(acc, w))) p.dynamic_parse(ctxt, v).and_then(|w| merge(acc, w))
})
}) })
} else { .and_then(|fixed_ws| {
None
}),
CompoundPattern::TuplePrefix { fixed, variable } =>
v.value().as_sequence().and_then(
|vs| if vs.len() >= fixed.len() {
fixed.iter().zip(vs)
.fold(Some(Map::new()), |acc, (p, v)| {
acc.and_then(|acc| p.dynamic_parse(ctxt, v).and_then(
|w| merge(acc, w)))
}).and_then(|fixed_ws| {
let remainder = V::new(vs[fixed.len()..].to_vec()); let remainder = V::new(vs[fixed.len()..].to_vec());
(**variable).dynamic_parse(ctxt, &remainder).and_then( (**variable).dynamic_parse(ctxt, &remainder).and_then(
|variable_ws| merge(fixed_ws, variable_ws.unwrap_compound())) |variable_ws| merge(fixed_ws, variable_ws.unwrap_compound()),
)
}) })
} else { } else {
None None
}), }
CompoundPattern::Dict { entries } => })
v.value().as_dictionary().and_then( }
|d| (**entries).0.iter().fold(Some(Map::new()), |acc, (k, p)| { CompoundPattern::Dict { entries } => v.value().as_dictionary().and_then(|d| {
acc.and_then(|acc| d.get(k).and_then(|v| p.dynamic_parse(ctxt, v).and_then( (**entries).0.iter().fold(Some(Map::new()), |acc, (k, p)| {
|w| merge(acc, w.unwrap_compound())))) acc.and_then(|acc| {
})), d.get(k).and_then(|v| {
p.dynamic_parse(ctxt, v)
.and_then(|w| merge(acc, w.unwrap_compound()))
})
})
})
}),
} }
} }
} }
@ -228,6 +281,9 @@ impl<V: NestedValue> DynField<V> {
} }
fn merge<V: NestedValue>(a: Map<V, V>, b: Map<V, V>) -> Option<Map<V, V>> { fn merge<V: NestedValue>(a: Map<V, V>, b: Map<V, V>) -> Option<Map<V, V>> {
merge2(V::new(a), V::new(b)) merge2(V::new(a), V::new(b)).map(|d| {
.map(|d| d.value_owned().into_dictionary().expect("merge to yield Dictionary")) d.value_owned()
.into_dictionary()
.expect("merge to yield Dictionary")
})
} }

View File

@ -1,8 +1,8 @@
pub use lazy_static::lazy_static; pub use lazy_static::lazy_static;
pub use preserves; pub use preserves;
pub use preserves::value::Reader;
pub use preserves::value::boundary as B; pub use preserves::value::boundary as B;
pub use preserves::value::Reader;
pub mod interpret; pub mod interpret;
@ -61,7 +61,7 @@ impl<L, N: NestedValue> Codec<N> for L {
pub trait Deserialize<N: NestedValue> pub trait Deserialize<N: NestedValue>
where where
Self: Sized Self: Sized,
{ {
fn deserialize<'de, R: Reader<'de, N>>(r: &mut R) -> Result<Self, ParseError>; fn deserialize<'de, R: Reader<'de, N>>(r: &mut R) -> Result<Self, ParseError>;
} }
@ -70,23 +70,19 @@ pub fn decode_lit<N: NestedValue>(bs: &[u8]) -> io::Result<N> {
preserves::value::packed::from_bytes(bs, NoEmbeddedDomainCodec) preserves::value::packed::from_bytes(bs, NoEmbeddedDomainCodec)
} }
pub fn decode_embedded<D: Domain>( pub fn decode_embedded<D: Domain>(v: &IOValue) -> Result<ArcValue<Arc<D>>, ParseError>
v: &IOValue,
) -> Result<ArcValue<Arc<D>>, ParseError>
where where
for<'a> D: TryFrom<&'a IOValue, Error = ParseError> for<'a> D: TryFrom<&'a IOValue, Error = ParseError>,
{ {
v.copy_via(&mut |d| Ok(Value::Embedded(Arc::new(D::try_from(d)?)))) v.copy_via(&mut |d| Ok(Value::Embedded(Arc::new(D::try_from(d)?))))
} }
pub fn encode_embedded<D: Domain>( pub fn encode_embedded<D: Domain>(v: &ArcValue<Arc<D>>) -> IOValue
v: &ArcValue<Arc<D>>,
) -> IOValue
where where
for<'a> IOValue: From<&'a D> for<'a> IOValue: From<&'a D>,
{ {
v.copy_via::<_, _, std::convert::Infallible>( v.copy_via::<_, _, std::convert::Infallible>(&mut |d| Ok(Value::Embedded(IOValue::from(d))))
&mut |d| Ok(Value::Embedded(IOValue::from(d)))).unwrap() .unwrap()
} }
#[derive(Error, Debug)] #[derive(Error, Debug)]
@ -100,10 +96,10 @@ pub enum ParseError {
impl From<preserves::error::Error> for ParseError { impl From<preserves::error::Error> for ParseError {
fn from(v: preserves::error::Error) -> Self { fn from(v: preserves::error::Error) -> Self {
match v { match v {
preserves::error::Error::Expected(_, _) => preserves::error::Error::Expected(_, _) => {
ParseError::ConformanceError("preserves::error::Error::Expected"), ParseError::ConformanceError("preserves::error::Error::Expected")
_ => }
ParseError::Preserves(v), _ => ParseError::Preserves(v),
} }
} }
} }
@ -129,6 +125,10 @@ impl ParseError {
} }
pub fn is_conformance_error(&self) -> bool { pub fn is_conformance_error(&self) -> bool {
return if let ParseError::ConformanceError(_) = self { true } else { false } return if let ParseError::ConformanceError(_) = self {
true
} else {
false
};
} }
} }

View File

@ -113,7 +113,10 @@ impl Emittable for String {
} }
} }
impl<'a, E: Emittable> Emittable for &'a Vec<E> where &'a E: Emittable { impl<'a, E: Emittable> Emittable for &'a Vec<E>
where
&'a E: Emittable,
{
fn write_on(&self, f: &mut Formatter) { fn write_on(&self, f: &mut Formatter) {
for e in self.iter() { for e in self.iter() {
f.write(e) f.write(e)
@ -159,8 +162,14 @@ impl Vertical for Sequence {
} }
first = false; first = false;
e.write_on(f); e.write_on(f);
let delim = if i == 1 { self.terminator } else { self.separator }; let delim = if i == 1 {
delim.trim_end_matches(|c: char| c.is_whitespace() && c != '\n').write_on(f); self.terminator
} else {
self.separator
};
delim
.trim_end_matches(|c: char| c.is_whitespace() && c != '\n')
.write_on(f);
i = i - 1; i = i - 1;
} }
} }
@ -263,43 +272,74 @@ pub fn escape_bytes(bs: &[u8]) -> String {
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
pub mod constructors { pub mod constructors {
use super::Sequence; use super::Emittable;
use super::Grouping; use super::Grouping;
use super::Item; use super::Item;
use super::Emittable; use super::Sequence;
use super::VerticalMode;
use super::Vertical; use super::Vertical;
use super::VerticalMode;
pub fn item<E: 'static + Emittable>(i: E) -> Item { pub fn item<E: 'static + Emittable>(i: E) -> Item {
std::rc::Rc::new(i) std::rc::Rc::new(i)
} }
pub fn name(pieces: Vec<Item>) -> Sequence { pub fn name(pieces: Vec<Item>) -> Sequence {
Sequence { items: pieces, vertical_mode: VerticalMode::default(), separator: "::", terminator: "" } Sequence {
items: pieces,
vertical_mode: VerticalMode::default(),
separator: "::",
terminator: "",
}
} }
pub fn seq(items: Vec<Item>) -> Sequence { pub fn seq(items: Vec<Item>) -> Sequence {
Sequence { items: items, vertical_mode: VerticalMode::default(), separator: "", terminator: "" } Sequence {
items: items,
vertical_mode: VerticalMode::default(),
separator: "",
terminator: "",
}
} }
pub fn commas(items: Vec<Item>) -> Sequence { pub fn commas(items: Vec<Item>) -> Sequence {
Sequence { items: items, vertical_mode: VerticalMode::default(), separator: ", ", terminator: "" } Sequence {
items: items,
vertical_mode: VerticalMode::default(),
separator: ", ",
terminator: "",
}
} }
pub fn parens(items: Vec<Item>) -> Grouping { pub fn parens(items: Vec<Item>) -> Grouping {
Grouping { sequence: commas(items), open: "(", close: ")" } Grouping {
sequence: commas(items),
open: "(",
close: ")",
}
} }
pub fn brackets(items: Vec<Item>) -> Grouping { pub fn brackets(items: Vec<Item>) -> Grouping {
Grouping { sequence: commas(items), open: "[", close: "]" } Grouping {
sequence: commas(items),
open: "[",
close: "]",
}
} }
pub fn anglebrackets(items: Vec<Item>) -> Grouping { pub fn anglebrackets(items: Vec<Item>) -> Grouping {
Grouping { sequence: commas(items), open: "<", close: ">" } Grouping {
sequence: commas(items),
open: "<",
close: ">",
}
} }
pub fn braces(items: Vec<Item>) -> Grouping { pub fn braces(items: Vec<Item>) -> Grouping {
Grouping { sequence: commas(items), open: "{", close: "}" } Grouping {
sequence: commas(items),
open: "{",
close: "}",
}
} }
pub fn block(items: Vec<Item>) -> Grouping { pub fn block(items: Vec<Item>) -> Grouping {
@ -333,12 +373,20 @@ pub mod constructors {
} }
pub fn vertical<V: Vertical>(spaced: bool, mut v: V) -> V { pub fn vertical<V: Vertical>(spaced: bool, mut v: V) -> V {
v.set_vertical_mode(if spaced { VerticalMode::ExtraNewline } else { VerticalMode::Normal }); v.set_vertical_mode(if spaced {
VerticalMode::ExtraNewline
} else {
VerticalMode::Normal
});
v v
} }
pub fn indented(sequence: Sequence) -> Grouping { pub fn indented(sequence: Sequence) -> Grouping {
Grouping { sequence, open: "", close: "" } Grouping {
sequence,
open: "",
close: "",
}
} }
} }

View File

@ -2,7 +2,7 @@ use bytes::Buf;
use bytes::BufMut; use bytes::BufMut;
use bytes::BytesMut; use bytes::BytesMut;
use clap:: {ArgEnum, Command, IntoApp, Parser, value_parser}; use clap::{value_parser, ArgEnum, Command, IntoApp, Parser};
use clap_complete::{generate, Generator, Shell}; use clap_complete::{generate, Generator, Shell};
use preserves::value::IOBinarySource; use preserves::value::IOBinarySource;
@ -21,9 +21,9 @@ use preserves::value::Writer;
use preserves::value::text::writer::CommaStyle; use preserves::value::text::writer::CommaStyle;
use std::iter::FromIterator;
use std::io; use std::io;
use std::io::Read; use std::io::Read;
use std::iter::FromIterator;
// #[derive(ArgEnum, Clone, Debug)] // #[derive(ArgEnum, Clone, Debug)]
// enum Encoding { // enum Encoding {
@ -90,7 +90,6 @@ struct Convert {
// #[clap(long, arg_enum, default_value = "none")] // #[clap(long, arg_enum, default_value = "none")]
// output_encoding: Encoding, // output_encoding: Encoding,
#[clap(long, short, arg_enum, default_value = "auto-detect")] #[clap(long, short, arg_enum, default_value = "auto-detect")]
input_format: InputFormat, input_format: InputFormat,
@ -109,10 +108,10 @@ struct Convert {
#[clap(long, arg_enum, value_name = "on/off", default_value = "on")] #[clap(long, arg_enum, value_name = "on/off", default_value = "on")]
indent: Boolish, indent: Boolish,
#[clap(long="select", default_value="*")] #[clap(long = "select", default_value = "*")]
select_expr: String, select_expr: String,
#[clap(long, arg_enum, default_value="sequence")] #[clap(long, arg_enum, default_value = "sequence")]
select_output: SelectOutput, select_output: SelectOutput,
#[clap(long)] #[clap(long)]
@ -126,7 +125,6 @@ struct Convert {
#[clap(long, value_name = "filename")] #[clap(long, value_name = "filename")]
bundle: Vec<std::path::PathBuf>, bundle: Vec<std::path::PathBuf>,
// #[clap(long)] // #[clap(long)]
// schema: Option<String>, // schema: Option<String>,
} }
@ -177,7 +175,7 @@ enum Subcommand {
} }
#[derive(Clone, Debug, Parser)] #[derive(Clone, Debug, Parser)]
#[clap(name="preserves-tool")] #[clap(name = "preserves-tool")]
#[clap(version)] #[clap(version)]
struct CommandLine { struct CommandLine {
#[clap(subcommand)] #[clap(subcommand)]
@ -194,7 +192,7 @@ fn main() -> io::Result<()> {
Subcommand::Completions { shell } => { Subcommand::Completions { shell } => {
let mut cmd = CommandLine::into_app(); let mut cmd = CommandLine::into_app();
print_completions(shell, &mut cmd); print_completions(shell, &mut cmd);
}, }
Subcommand::Convert(c) => convert(c)?, Subcommand::Convert(c) => convert(c)?,
Subcommand::Quote(q) => quote(q)?, Subcommand::Quote(q) => quote(q)?,
}) })
@ -220,7 +218,7 @@ impl<R: io::Read> RollingBuffer<R> {
fn read_more(&mut self) -> io::Result<usize> { fn read_more(&mut self) -> io::Result<usize> {
let mut buf = [0; 8192]; let mut buf = [0; 8192];
let n = self.r.read(&mut buf)?; let n = self.r.read(&mut buf)?;
self.buf.put(&buf[.. n]); self.buf.put(&buf[..n]);
Ok(n) Ok(n)
} }
@ -228,7 +226,7 @@ impl<R: io::Read> RollingBuffer<R> {
if self.rhs() == self.pos { if self.rhs() == self.pos {
let _ = self.read_more()?; let _ = self.read_more()?;
} }
return Ok(&self.buf[self.pos - self.discarded ..]); return Ok(&self.buf[self.pos - self.discarded..]);
} }
fn rhs(&self) -> usize { fn rhs(&self) -> usize {
@ -256,29 +254,41 @@ impl<R: io::Read> RollingBuffer<R> {
} }
result.push(buf[0]); result.push(buf[0]);
} }
Ok(if result.is_empty() { None } else { Some(result) }) Ok(if result.is_empty() {
None
} else {
Some(result)
})
} }
} }
impl<R: io::Read> io::Seek for RollingBuffer<R> { impl<R: io::Read> io::Seek for RollingBuffer<R> {
fn seek(&mut self, offset: io::SeekFrom) -> io::Result<u64> { fn seek(&mut self, offset: io::SeekFrom) -> io::Result<u64> {
let new_position = match offset { let new_position = match offset {
io::SeekFrom::Current(delta) => if delta >= 0 { io::SeekFrom::Current(delta) => {
self.pos + delta as usize if delta >= 0 {
} else { self.pos + delta as usize
self.pos - (-delta) as usize } else {
}, self.pos - (-delta) as usize
}
}
io::SeekFrom::End(_) => Err(io::Error::new( io::SeekFrom::End(_) => Err(io::Error::new(
io::ErrorKind::Unsupported, "Cannot seek wrt end on open-ended stream"))?, io::ErrorKind::Unsupported,
"Cannot seek wrt end on open-ended stream",
))?,
io::SeekFrom::Start(new_position) => new_position as usize, io::SeekFrom::Start(new_position) => new_position as usize,
}; };
if new_position > self.rhs() { if new_position > self.rhs() {
Err(io::Error::new( Err(io::Error::new(
io::ErrorKind::InvalidInput, "Attempt to seek beyond end of buffer"))?; io::ErrorKind::InvalidInput,
"Attempt to seek beyond end of buffer",
))?;
} }
if new_position < self.discarded { if new_position < self.discarded {
Err(io::Error::new( Err(io::Error::new(
io::ErrorKind::InvalidInput, "Attempt to seek before start of buffer"))?; io::ErrorKind::InvalidInput,
"Attempt to seek before start of buffer",
))?;
} }
self.pos = new_position; self.pos = new_position;
Ok(new_position as u64) Ok(new_position as u64)
@ -293,14 +303,14 @@ impl<R: io::Read> io::Read for RollingBuffer<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let i = self.pos - self.discarded; let i = self.pos - self.discarded;
loop { loop {
let n = std::cmp::min(self.buf.remaining() - i , buf.len()); let n = std::cmp::min(self.buf.remaining() - i, buf.len());
if n == 0 { if n == 0 {
if self.read_more()? == 0 { if self.read_more()? == 0 {
return Ok(0); return Ok(0);
} }
continue; continue;
} }
let _ = &buf[.. n].copy_from_slice(&self.buf[i .. i + n]); let _ = &buf[..n].copy_from_slice(&self.buf[i..i + n]);
self.pos += n; self.pos += n;
return Ok(n); return Ok(n);
} }
@ -337,19 +347,26 @@ impl<R: io::Read> ValueStream<R> {
let maybe_value: Option<IOValue> = if is_text { let maybe_value: Option<IOValue> = if is_text {
match self.input_format { match self.input_format {
InputFormat::AutoDetect | InputFormat::Text => (), InputFormat::AutoDetect | InputFormat::Text => (),
InputFormat::Binary => return Err(io::Error::new( InputFormat::Binary => {
io::ErrorKind::InvalidData, "Expected binary input, saw text input")), return Err(io::Error::new(
io::ErrorKind::InvalidData,
"Expected binary input, saw text input",
))
}
} }
TextReader::new(&mut self.source, ViaCodec::new(IOValueDomainCodec)) TextReader::new(&mut self.source, ViaCodec::new(IOValueDomainCodec))
.next(self.read_annotations)? .next(self.read_annotations)?
} else { } else {
match self.input_format { match self.input_format {
InputFormat::AutoDetect | InputFormat::Binary => (), InputFormat::AutoDetect | InputFormat::Binary => (),
InputFormat::Text => return Err(io::Error::new( InputFormat::Text => {
io::ErrorKind::InvalidData, "Expected text input, saw binary input")), return Err(io::Error::new(
io::ErrorKind::InvalidData,
"Expected text input, saw binary input",
))
}
} }
PackedReader::new(&mut self.source, IOValueDomainCodec) PackedReader::new(&mut self.source, IOValueDomainCodec).next(self.read_annotations)?
.next(self.read_annotations)?
}; };
match maybe_value { match maybe_value {
@ -383,10 +400,12 @@ fn convert(c: Convert) -> io::Result<()> {
for f in c.bundle.iter() { for f in c.bundle.iter() {
env.load_bundle(f)?; env.load_bundle(f)?;
} }
let select = preserves_path::Node::from_str(&env, &c.select_expr) let select = preserves_path::Node::from_str(&env, &c.select_expr).map_err(|e| {
.map_err(|e| io::Error::new( io::Error::new(
io::ErrorKind::InvalidData, io::ErrorKind::InvalidData,
format!("Invalid select expression: {}: {:?}", e, c.select_expr)))?; format!("Invalid select expression: {}: {:?}", e, c.select_expr),
)
})?;
let mut vs = ValueStream::new(c.input_format, c.read_annotations.into(), io::stdin()); let mut vs = ValueStream::new(c.input_format, c.read_annotations.into(), io::stdin());
let write_ann: bool = c.write_annotations.into(); let write_ann: bool = c.write_annotations.into();
let mut w: Box<dyn FnMut(&IOValue) -> io::Result<()>> = match c.output_format { let mut w: Box<dyn FnMut(&IOValue) -> io::Result<()>> = match c.output_format {
@ -418,11 +437,10 @@ fn convert(c: Convert) -> io::Result<()> {
Ok(()) Ok(())
}) })
} }
OutputFormat::Unquoted => OutputFormat::Unquoted => Box::new(|v| {
Box::new(|v| { print_unquoted(v);
print_unquoted(v); Ok(())
Ok(()) }),
}),
}; };
while let Some(value) = vs.next() { while let Some(value) = vs.next() {
let value = value?; let value = value?;
@ -434,8 +452,16 @@ fn convert(c: Convert) -> io::Result<()> {
} }
} else { } else {
match c.select_output { match c.select_output {
SelectOutput::Sequence => for v in matches { w(&v)?; }, SelectOutput::Sequence => {
SelectOutput::Set => for v in Set::from_iter(matches) { w(&v)?; }, for v in matches {
w(&v)?;
}
}
SelectOutput::Set => {
for v in Set::from_iter(matches) {
w(&v)?;
}
}
} }
} }
if let Some(limit) = c.limit { if let Some(limit) = c.limit {
@ -458,8 +484,7 @@ impl Quote {
fn output_one(q: &Quote, v: &IOValue) -> io::Result<()> { fn output_one(q: &Quote, v: &IOValue) -> io::Result<()> {
match q.output_format { match q.output_format {
OutputFormat::Binary => OutputFormat::Binary => PackedWriter::new(io::stdout()).write(&mut IOValueDomainCodec, v),
PackedWriter::new(io::stdout()).write(&mut IOValueDomainCodec, v),
OutputFormat::Text => { OutputFormat::Text => {
TextWriter::new(io::stdout()) TextWriter::new(io::stdout())
.set_escape_spaces(q.escape_spaces()) .set_escape_spaces(q.escape_spaces())
@ -480,18 +505,16 @@ fn quote(q: Quote) -> io::Result<()> {
let mut buf = Vec::new(); let mut buf = Vec::new();
io::stdin().read_to_end(&mut buf)?; io::stdin().read_to_end(&mut buf)?;
output_one(&q, &IOValue::new(&buf[..])) output_one(&q, &IOValue::new(&buf[..]))
},
QuotationOutput::String(s) | QuotationOutput::Symbol(s) => {
match s.input_terminator {
StringInputTerminator::EOF => {
let mut buf = String::new();
io::stdin().read_to_string(&mut buf)?;
quote_chunk(&q, buf)
}
StringInputTerminator::Newline => quote_terminated_strings(b'\n', &q, s),
StringInputTerminator::Nul => quote_terminated_strings(b'\0', &q, s),
}
} }
QuotationOutput::String(s) | QuotationOutput::Symbol(s) => match s.input_terminator {
StringInputTerminator::EOF => {
let mut buf = String::new();
io::stdin().read_to_string(&mut buf)?;
quote_chunk(&q, buf)
}
StringInputTerminator::Newline => quote_terminated_strings(b'\n', &q, s),
StringInputTerminator::Nul => quote_terminated_strings(b'\0', &q, s),
},
} }
} }
@ -505,8 +528,11 @@ fn quote_chunk(q: &Quote, buf: String) -> io::Result<()> {
fn quote_terminated_strings(delimiter: u8, q: &Quote, s: &StringQuotation) -> io::Result<()> { fn quote_terminated_strings(delimiter: u8, q: &Quote, s: &StringQuotation) -> io::Result<()> {
let mut r = RollingBuffer::new(io::stdin()); let mut r = RollingBuffer::new(io::stdin());
while let Some(chunk) = r.read_upto(delimiter, s.include_terminator)? { while let Some(chunk) = r.read_upto(delimiter, s.include_terminator)? {
quote_chunk(q, String::from_utf8(chunk).map_err( quote_chunk(
|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8"))?)? q,
String::from_utf8(chunk)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8"))?,
)?
} }
Ok(()) Ok(())
} }

View File

@ -1,6 +1,8 @@
use criterion::{criterion_group, criterion_main, Criterion}; use criterion::{criterion_group, criterion_main, Criterion};
use preserves::de; use preserves::de;
use preserves::ser; use preserves::ser;
use preserves::value;
use preserves::value::packed::annotated_iovalue_from_bytes;
use preserves::value::BinarySource; use preserves::value::BinarySource;
use preserves::value::BytesBinarySource; use preserves::value::BytesBinarySource;
use preserves::value::IOBinarySource; use preserves::value::IOBinarySource;
@ -8,12 +10,10 @@ use preserves::value::IOValueDomainCodec;
use preserves::value::PackedWriter; use preserves::value::PackedWriter;
use preserves::value::Reader; use preserves::value::Reader;
use preserves::value::Writer; use preserves::value::Writer;
use preserves::value::packed::annotated_iovalue_from_bytes;
use preserves::value;
use std::fs::File; use std::fs::File;
use std::io;
use std::io::Read; use std::io::Read;
use std::io::Seek; use std::io::Seek;
use std::io;
#[path = "../tests/samples/mod.rs"] #[path = "../tests/samples/mod.rs"]
mod samples; mod samples;
@ -23,64 +23,87 @@ pub fn bench_decoder_bytes(c: &mut Criterion) {
let mut fh = File::open("../../../tests/samples.bin").unwrap(); let mut fh = File::open("../../../tests/samples.bin").unwrap();
let mut bs = vec![]; let mut bs = vec![];
fh.read_to_end(&mut bs).ok(); fh.read_to_end(&mut bs).ok();
c.bench_function("decode samples.bin via bytes", |b| b.iter_with_large_drop( c.bench_function("decode samples.bin via bytes", |b| {
|| annotated_iovalue_from_bytes(&bs[..]).unwrap())); b.iter_with_large_drop(|| annotated_iovalue_from_bytes(&bs[..]).unwrap())
});
} }
pub fn bench_decoder_file(c: &mut Criterion) { pub fn bench_decoder_file(c: &mut Criterion) {
let mut fh = File::open("../../../tests/samples.bin").unwrap(); let mut fh = File::open("../../../tests/samples.bin").unwrap();
c.bench_function("decode samples.bin via file", |b| b.iter_with_large_drop(|| { c.bench_function("decode samples.bin via file", |b| {
fh.seek(io::SeekFrom::Start(0)).ok(); b.iter_with_large_drop(|| {
IOBinarySource::new(&mut fh).packed_iovalues().demand_next(true).unwrap() fh.seek(io::SeekFrom::Start(0)).ok();
})); IOBinarySource::new(&mut fh)
.packed_iovalues()
.demand_next(true)
.unwrap()
})
});
} }
pub fn bench_decoder_buffered_file(c: &mut Criterion) { pub fn bench_decoder_buffered_file(c: &mut Criterion) {
let mut fh = io::BufReader::new(File::open("../../../tests/samples.bin").unwrap()); let mut fh = io::BufReader::new(File::open("../../../tests/samples.bin").unwrap());
c.bench_function("decode samples.bin via buffered file", |b| b.iter_with_large_drop(|| { c.bench_function("decode samples.bin via buffered file", |b| {
fh.seek(io::SeekFrom::Start(0)).ok(); b.iter_with_large_drop(|| {
IOBinarySource::new(&mut fh).packed_iovalues().demand_next(true).unwrap() fh.seek(io::SeekFrom::Start(0)).ok();
})); IOBinarySource::new(&mut fh)
.packed_iovalues()
.demand_next(true)
.unwrap()
})
});
} }
pub fn bench_encoder(c: &mut Criterion) { pub fn bench_encoder(c: &mut Criterion) {
let mut fh = File::open("../../../tests/samples.bin").unwrap(); let mut fh = File::open("../../../tests/samples.bin").unwrap();
let v = IOBinarySource::new(&mut fh).packed_iovalues().demand_next(true).unwrap(); let v = IOBinarySource::new(&mut fh)
c.bench_function("encode samples.bin", |b| b.iter_with_large_drop( .packed_iovalues()
|| PackedWriter::encode_iovalue(&v).unwrap())); .demand_next(true)
.unwrap();
c.bench_function("encode samples.bin", |b| {
b.iter_with_large_drop(|| PackedWriter::encode_iovalue(&v).unwrap())
});
} }
pub fn bench_de(c: &mut Criterion) { pub fn bench_de(c: &mut Criterion) {
let mut fh = File::open("../../../tests/samples.bin").unwrap(); let mut fh = File::open("../../../tests/samples.bin").unwrap();
let mut bs = vec![]; let mut bs = vec![];
fh.read_to_end(&mut bs).ok(); fh.read_to_end(&mut bs).ok();
c.bench_function("deserialize samples.bin", |b| b.iter_with_large_drop( c.bench_function("deserialize samples.bin", |b| {
|| de::from_bytes::<TestCases>(&bs[..]).unwrap())); b.iter_with_large_drop(|| de::from_bytes::<TestCases>(&bs[..]).unwrap())
});
} }
pub fn bench_ser(c: &mut Criterion) { pub fn bench_ser(c: &mut Criterion) {
let mut fh = File::open("../../../tests/samples.bin").unwrap(); let mut fh = File::open("../../../tests/samples.bin").unwrap();
let v: TestCases = de::from_read(&mut fh).unwrap(); let v: TestCases = de::from_read(&mut fh).unwrap();
c.bench_function("serialize samples.bin", |b| b.iter_with_large_drop(|| { c.bench_function("serialize samples.bin", |b| {
let mut bs = vec![]; b.iter_with_large_drop(|| {
ser::to_writer(&mut PackedWriter::new(&mut bs), &v).unwrap(); let mut bs = vec![];
bs ser::to_writer(&mut PackedWriter::new(&mut bs), &v).unwrap();
})); bs
})
});
} }
pub fn bench_decoder_de(c: &mut Criterion) { pub fn bench_decoder_de(c: &mut Criterion) {
let mut fh = File::open("../../../tests/samples.bin").unwrap(); let mut fh = File::open("../../../tests/samples.bin").unwrap();
let mut bs = vec![]; let mut bs = vec![];
fh.read_to_end(&mut bs).ok(); fh.read_to_end(&mut bs).ok();
c.bench_function("decode-then-deserialize samples.bin", |b| b.iter_with_large_drop( c.bench_function("decode-then-deserialize samples.bin", |b| {
|| value::de::from_value::<TestCases>(&annotated_iovalue_from_bytes(&bs[..]).unwrap()).unwrap())); b.iter_with_large_drop(|| {
value::de::from_value::<TestCases>(&annotated_iovalue_from_bytes(&bs[..]).unwrap())
.unwrap()
})
});
} }
pub fn bench_ser_encoder(c: &mut Criterion) { pub fn bench_ser_encoder(c: &mut Criterion) {
let mut fh = File::open("../../../tests/samples.bin").unwrap(); let mut fh = File::open("../../../tests/samples.bin").unwrap();
let v: TestCases = de::from_read(&mut fh).unwrap(); let v: TestCases = de::from_read(&mut fh).unwrap();
c.bench_function("serialize-then-encode samples.bin", |b| b.iter_with_large_drop( c.bench_function("serialize-then-encode samples.bin", |b| {
|| PackedWriter::encode_iovalue(&value::ser::to_value(&v)).unwrap())); b.iter_with_large_drop(|| PackedWriter::encode_iovalue(&value::ser::to_value(&v)).unwrap())
});
} }
pub fn large_testdata_decoder_with_ann(c: &mut Criterion) { pub fn large_testdata_decoder_with_ann(c: &mut Criterion) {
@ -130,12 +153,16 @@ pub fn large_testdata_encoder(c: &mut Criterion) {
}); });
} }
criterion_group!(codec, criterion_group!(
bench_decoder_bytes, bench_decoder_file, bench_decoder_buffered_file, codec,
bench_encoder); bench_decoder_bytes,
bench_decoder_file,
bench_decoder_buffered_file,
bench_encoder
);
criterion_group!(serde, bench_de, bench_ser); criterion_group!(serde, bench_de, bench_ser);
criterion_group!(codec_then_serde, bench_decoder_de, bench_ser_encoder); criterion_group!(codec_then_serde, bench_decoder_de, bench_ser_encoder);
criterion_group!{ criterion_group! {
name = large_testdata; name = large_testdata;
config = Criterion::default().sample_size(10); config = Criterion::default().sample_size(10);
targets = large_testdata_decoder_with_ann, large_testdata_decoder_without_ann, large_testdata_encoder targets = large_testdata_decoder_with_ann, large_testdata_decoder_without_ann, large_testdata_encoder

View File

@ -1,5 +1,8 @@
use preserves::{de, value::{self, Reader, IOBinarySource, BinarySource}}; use preserves::{
use serde::{Serialize, Deserialize}; de,
value::{self, BinarySource, IOBinarySource, Reader},
};
use serde::{Deserialize, Serialize};
use std::fs::File; use std::fs::File;
use std::io; use std::io;
@ -10,7 +13,6 @@ enum Fruit {
Banana(Weight, Colour, u8), Banana(Weight, Colour, u8),
// Peach, // Peach,
#[serde(other)] #[serde(other)]
Unknown, Unknown,
} }
@ -33,7 +35,9 @@ enum Variety {
} }
fn try_file(kind: &str, path: &str) -> io::Result<()> { fn try_file(kind: &str, path: &str) -> io::Result<()> {
let fruits_value = IOBinarySource::new(&mut File::open(path)?).packed_iovalues().demand_next(true)?; let fruits_value = IOBinarySource::new(&mut File::open(path)?)
.packed_iovalues()
.demand_next(true)?;
println!("{:#?}", fruits_value); println!("{:#?}", fruits_value);
let fruits1: Vec<Fruit> = value::de::from_value(&fruits_value)?; let fruits1: Vec<Fruit> = value::de::from_value(&fruits_value)?;

View File

@ -1,13 +1,13 @@
use serde::de::{DeserializeSeed, EnumAccess, MapAccess, SeqAccess, VariantAccess, Visitor};
use serde::Deserialize; use serde::Deserialize;
use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
use std::borrow::Cow; use std::borrow::Cow;
use std::io; use std::io;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::value::boundary as B; use super::value::boundary as B;
use super::value::reader::{BytesBinarySource, IOBinarySource, Reader};
use super::value::{IOValue, IOValueDomainCodec, PackedReader, TextReader, ViaCodec}; use super::value::{IOValue, IOValueDomainCodec, PackedReader, TextReader, ViaCodec};
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource};
pub use super::error::Error; pub use super::error::Error;
@ -18,31 +18,39 @@ pub struct Deserializer<'de, 'r, R: Reader<'de, IOValue>> {
phantom: PhantomData<&'de ()>, phantom: PhantomData<&'de ()>,
} }
pub fn from_bytes<'de, T>(bytes: &'de [u8]) -> pub fn from_bytes<'de, T>(bytes: &'de [u8]) -> Result<T>
Result<T>
where where
T: Deserialize<'de> T: Deserialize<'de>,
{ {
from_reader(&mut PackedReader::new(&mut BytesBinarySource::new(bytes), IOValueDomainCodec)) from_reader(&mut PackedReader::new(
&mut BytesBinarySource::new(bytes),
IOValueDomainCodec,
))
} }
pub fn from_text<'de, T>(text: &'de str) -> Result<T> where T: Deserialize<'de> { pub fn from_text<'de, T>(text: &'de str) -> Result<T>
from_reader(&mut TextReader::new(&mut BytesBinarySource::new(text.as_bytes()),
ViaCodec::new(IOValueDomainCodec)))
}
pub fn from_read<'de, 'r, IOR: io::Read + io::Seek, T>(read: &'r mut IOR) ->
Result<T>
where where
T: Deserialize<'de> T: Deserialize<'de>,
{ {
from_reader(&mut PackedReader::new(&mut IOBinarySource::new(read), IOValueDomainCodec)) from_reader(&mut TextReader::new(
&mut BytesBinarySource::new(text.as_bytes()),
ViaCodec::new(IOValueDomainCodec),
))
} }
pub fn from_reader<'r, 'de, R: Reader<'de, IOValue>, T>(read: &'r mut R) -> pub fn from_read<'de, 'r, IOR: io::Read + io::Seek, T>(read: &'r mut IOR) -> Result<T>
Result<T>
where where
T: Deserialize<'de> T: Deserialize<'de>,
{
from_reader(&mut PackedReader::new(
&mut IOBinarySource::new(read),
IOValueDomainCodec,
))
}
pub fn from_reader<'r, 'de, R: Reader<'de, IOValue>, T>(read: &'r mut R) -> Result<T>
where
T: Deserialize<'de>,
{ {
let mut de = Deserializer::from_reader(read); let mut de = Deserializer::from_reader(read);
let t = T::deserialize(&mut de)?; let t = T::deserialize(&mut de)?;
@ -51,83 +59,113 @@ where
impl<'r, 'de, R: Reader<'de, IOValue>> Deserializer<'de, 'r, R> { impl<'r, 'de, R: Reader<'de, IOValue>> Deserializer<'de, 'r, R> {
pub fn from_reader(read: &'r mut R) -> Self { pub fn from_reader(read: &'r mut R) -> Self {
Deserializer { read, phantom: PhantomData } Deserializer {
read,
phantom: PhantomData,
}
} }
} }
impl<'r, 'de, 'a, R: Reader<'de, IOValue>> impl<'r, 'de, 'a, R: Reader<'de, IOValue>> serde::de::Deserializer<'de>
serde::de::Deserializer<'de>
for &'a mut Deserializer<'de, 'r, R> for &'a mut Deserializer<'de, 'r, R>
{ {
type Error = Error; type Error = Error;
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
// Won't support this here -- use value::de::Deserializer for this // Won't support this here -- use value::de::Deserializer for this
Err(Error::CannotDeserializeAny) Err(Error::CannotDeserializeAny)
} }
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_bool(self.read.next_boolean()?) visitor.visit_bool(self.read.next_boolean()?)
} }
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_i8(self.read.next_i8()?) visitor.visit_i8(self.read.next_i8()?)
} }
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_i16(self.read.next_i16()?) visitor.visit_i16(self.read.next_i16()?)
} }
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_i32(self.read.next_i32()?) visitor.visit_i32(self.read.next_i32()?)
} }
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_i64(self.read.next_i64()?) visitor.visit_i64(self.read.next_i64()?)
} }
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_u8(self.read.next_u8()?) visitor.visit_u8(self.read.next_u8()?)
} }
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_u16(self.read.next_u16()?) visitor.visit_u16(self.read.next_u16()?)
} }
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_u32(self.read.next_u32()?) visitor.visit_u32(self.read.next_u32()?)
} }
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_u64(self.read.next_u64()?) visitor.visit_u64(self.read.next_u64()?)
} }
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_f32(self.read.next_f32()?) visitor.visit_f32(self.read.next_f32()?)
} }
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_f64(self.read.next_f64()?) visitor.visit_f64(self.read.next_f64()?)
} }
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_char(self.read.next_char()?) visitor.visit_char(self.read.next_char()?)
} }
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
match self.read.next_str()? { match self.read.next_str()? {
Cow::Borrowed(s) => visitor.visit_borrowed_str(s), Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
@ -135,12 +173,16 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
} }
} }
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
self.deserialize_str(visitor) self.deserialize_str(visitor)
} }
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
match self.read.next_bytestring()? { match self.read.next_bytestring()? {
Cow::Borrowed(bs) => visitor.visit_borrowed_bytes(bs), Cow::Borrowed(bs) => visitor.visit_borrowed_bytes(bs),
@ -148,15 +190,20 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
} }
} }
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_byte_buf(self.read.next_bytestring()?.into_owned()) visitor.visit_byte_buf(self.read.next_bytestring()?.into_owned())
} }
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
if let Some(mut b) = self.read.open_option()? { if let Some(mut b) = self.read.open_option()? {
self.read.ensure_more_expected(&mut b, &B::Item::RecordField)?; self.read
.ensure_more_expected(&mut b, &B::Item::RecordField)?;
let result = visitor.visit_some(&mut *self)?; let result = visitor.visit_some(&mut *self)?;
self.read.ensure_complete(b, &B::Item::RecordField)?; self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result) Ok(result)
@ -165,7 +212,9 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
} }
} }
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
let b = self.read.open_simple_record("tuple", Some(0))?; let b = self.read.open_simple_record("tuple", Some(0))?;
let result = visitor.visit_unit::<Error>()?; let result = visitor.visit_unit::<Error>()?;
@ -173,8 +222,9 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
Ok(result) Ok(result)
} }
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
-> Result<V::Value> where V: Visitor<'de> where
V: Visitor<'de>,
{ {
let b = self.read.open_simple_record(name, Some(0))?; let b = self.read.open_simple_record(name, Some(0))?;
let result = visitor.visit_unit::<Error>()?; let result = visitor.visit_unit::<Error>()?;
@ -182,16 +232,18 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
Ok(result) Ok(result)
} }
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
-> Result<V::Value> where V: Visitor<'de> where
V: Visitor<'de>,
{ {
match super::value::magic::transmit_input_value( match super::value::magic::transmit_input_value(name, || {
name, || Ok(self.read.demand_next(true)?))? Ok(self.read.demand_next(true)?)
{ })? {
Some(v) => visitor.visit_u64(v), Some(v) => visitor.visit_u64(v),
None => { None => {
let mut b = self.read.open_simple_record(name, Some(1))?; let mut b = self.read.open_simple_record(name, Some(1))?;
self.read.ensure_more_expected(&mut b, &B::Item::RecordField)?; self.read
.ensure_more_expected(&mut b, &B::Item::RecordField)?;
let result = visitor.visit_newtype_struct(&mut *self)?; let result = visitor.visit_newtype_struct(&mut *self)?;
self.read.ensure_complete(b, &B::Item::RecordField)?; self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result) Ok(result)
@ -199,14 +251,19 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
} }
} }
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> { fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
// Hack around serde's model: Deserialize *sets* as sequences, // Hack around serde's model: Deserialize *sets* as sequences,
// too, and reconstruct them as Rust Sets on the visitor side. // too, and reconstruct them as Rust Sets on the visitor side.
let i = self.read.open_sequence_or_set()?; let i = self.read.open_sequence_or_set()?;
visitor.visit_seq(Seq::new(self, B::Type::default(), i)) visitor.visit_seq(Seq::new(self, B::Type::default(), i))
} }
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
let b = self.read.open_simple_record("tuple", Some(len))?; let b = self.read.open_simple_record("tuple", Some(len))?;
let mut seq = Seq::new(self, b, B::Item::RecordField); let mut seq = Seq::new(self, b, B::Item::RecordField);
@ -215,8 +272,14 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
Ok(result) Ok(result)
} }
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) fn deserialize_tuple_struct<V>(
-> Result<V::Value> where V: Visitor<'de> self,
name: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
let b = self.read.open_simple_record(name, Some(len))?; let b = self.read.open_simple_record(name, Some(len))?;
let mut seq = Seq::new(self, b, B::Item::RecordField); let mut seq = Seq::new(self, b, B::Item::RecordField);
@ -225,18 +288,24 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
Ok(result) Ok(result)
} }
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> { fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.read.open_dictionary()?; self.read.open_dictionary()?;
let mut seq = Seq::new(self, B::Type::default(), B::Item::DictionaryKey); let mut seq = Seq::new(self, B::Type::default(), B::Item::DictionaryKey);
let result = visitor.visit_map(&mut seq)?; let result = visitor.visit_map(&mut seq)?;
Ok(result) Ok(result)
} }
fn deserialize_struct<V>(self, fn deserialize_struct<V>(
name: &'static str, self,
fields: &'static [&'static str], name: &'static str,
visitor: V) fields: &'static [&'static str],
-> Result<V::Value> where V: Visitor<'de> visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
let b = self.read.open_simple_record(name, Some(fields.len()))?; let b = self.read.open_simple_record(name, Some(fields.len()))?;
let mut seq = Seq::new(self, b, B::Item::RecordField); let mut seq = Seq::new(self, b, B::Item::RecordField);
@ -245,16 +314,21 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
Ok(result) Ok(result)
} }
fn deserialize_enum<V>(self, fn deserialize_enum<V>(
_name: &'static str, self,
_variants: &'static [&'static str], _name: &'static str,
visitor: V) _variants: &'static [&'static str],
-> Result<V::Value> where V: Visitor<'de> visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_enum(self) visitor.visit_enum(self)
} }
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
match self.read.next_symbol()? { match self.read.next_symbol()? {
Cow::Borrowed(s) => visitor.visit_borrowed_str(s), Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
@ -262,7 +336,9 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
} }
} }
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_none() visitor.visit_none()
} }
@ -286,8 +362,9 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> Seq<'de, 'r, 'a, R> {
Ok(()) Ok(())
} }
fn next_item<T>(&mut self, seed: T) -> fn next_item<T>(&mut self, seed: T) -> Result<Option<T::Value>>
Result<Option<T::Value>> where T: DeserializeSeed<'de> where
T: DeserializeSeed<'de>,
{ {
match self.de.read.close_compound(&mut self.b, &self.i)? { match self.de.read.close_compound(&mut self.b, &self.i)? {
true => Ok(None), true => Ok(None),
@ -299,8 +376,9 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> Seq<'de, 'r, 'a, R> {
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> SeqAccess<'de> for Seq<'de, 'r, 'a, R> { impl<'de, 'r, 'a, R: Reader<'de, IOValue>> SeqAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error; type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
Result<Option<T::Value>> where T: DeserializeSeed<'de> where
T: DeserializeSeed<'de>,
{ {
Ok(self.next_item(seed)?) Ok(self.next_item(seed)?)
} }
@ -309,15 +387,17 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> SeqAccess<'de> for Seq<'de, 'r, 'a, R
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> MapAccess<'de> for Seq<'de, 'r, 'a, R> { impl<'de, 'r, 'a, R: Reader<'de, IOValue>> MapAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error; type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
Result<Option<K::Value>> where K: DeserializeSeed<'de> where
K: DeserializeSeed<'de>,
{ {
self.i = B::Item::DictionaryKey; self.i = B::Item::DictionaryKey;
self.next_item(seed) self.next_item(seed)
} }
fn next_value_seed<V>(&mut self, seed: V) -> fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
Result<V::Value> where V: DeserializeSeed<'de> where
V: DeserializeSeed<'de>,
{ {
self.i = B::Item::DictionaryValue; self.i = B::Item::DictionaryValue;
match self.next_item(seed)? { match self.next_item(seed)? {
@ -331,8 +411,9 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> EnumAccess<'de> for &'a mut Deseriali
type Error = Error; type Error = Error;
type Variant = Seq<'de, 'r, 'a, R>; type Variant = Seq<'de, 'r, 'a, R>;
fn variant_seed<V>(self, seed: V) fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de> where
V: DeserializeSeed<'de>,
{ {
let b = self.read.open_record(None)?; let b = self.read.open_record(None)?;
let variant = seed.deserialize(&mut *self)?; let variant = seed.deserialize(&mut *self)?;
@ -347,7 +428,10 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> VariantAccess<'de> for Seq<'de, 'r, '
self.skip_remainder() self.skip_remainder()
} }
fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value> where T: DeserializeSeed<'de> { fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value>
where
T: DeserializeSeed<'de>,
{
match self.next_item(seed)? { match self.next_item(seed)? {
None => Err(Error::MissingItem), None => Err(Error::MissingItem),
Some(v) => { Some(v) => {
@ -357,20 +441,18 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> VariantAccess<'de> for Seq<'de, 'r, '
} }
} }
fn tuple_variant<V>(mut self, _len: usize, visitor: V) -> fn tuple_variant<V>(mut self, _len: usize, visitor: V) -> Result<V::Value>
Result<V::Value>
where where
V: Visitor<'de> V: Visitor<'de>,
{ {
let result = visitor.visit_seq(&mut self)?; let result = visitor.visit_seq(&mut self)?;
self.skip_remainder()?; self.skip_remainder()?;
Ok(result) Ok(result)
} }
fn struct_variant<V>(mut self, _fields: &'static [&'static str], visitor: V) -> fn struct_variant<V>(mut self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
Result<V::Value>
where where
V: Visitor<'de> V: Visitor<'de>,
{ {
let result = visitor.visit_seq(&mut self)?; let result = visitor.visit_seq(&mut self)?;
self.skip_remainder()?; self.skip_remainder()?;

View File

@ -20,20 +20,24 @@ impl HexParser {
let mut buf_full = false; let mut buf_full = false;
for c in s.chars() { for c in s.chars() {
match c.to_digit(16) { match c.to_digit(16) {
None => None => match self {
match self { HexParser::Liberal => (),
HexParser::Liberal => (), HexParser::WhitespaceAllowed => {
HexParser::WhitespaceAllowed => if !c.is_whitespace() { return None }, if !c.is_whitespace() {
HexParser::Strict => return None, return None;
}, }
Some(nibble) => }
HexParser::Strict => return None,
},
Some(nibble) => {
if buf_full { if buf_full {
result.push(buf << 4 | (nibble as u8)); result.push(buf << 4 | (nibble as u8));
buf_full = false; buf_full = false;
} else { } else {
buf = nibble as u8; buf = nibble as u8;
buf_full = true; buf_full = true;
}, }
}
} }
} }
if buf_full { if buf_full {
@ -76,42 +80,89 @@ impl HexFormatter {
mod test { mod test {
use super::*; use super::*;
#[test] fn test_decode_packed() { #[test]
fn test_decode_packed() {
let s = "01ab00ff"; let s = "01ab00ff";
assert_eq!(HexParser::Strict.decode(s), Some(vec![1, 171, 0, 255])); assert_eq!(HexParser::Strict.decode(s), Some(vec![1, 171, 0, 255]));
assert_eq!(HexParser::WhitespaceAllowed.decode(s), Some(vec![1, 171, 0, 255])); assert_eq!(
HexParser::WhitespaceAllowed.decode(s),
Some(vec![1, 171, 0, 255])
);
assert_eq!(HexParser::Liberal.decode(s), Some(vec![1, 171, 0, 255])); assert_eq!(HexParser::Liberal.decode(s), Some(vec![1, 171, 0, 255]));
} }
#[test] fn test_decode_whitespace() { #[test]
fn test_decode_whitespace() {
let s = "01ab 00ff"; let s = "01ab 00ff";
assert_eq!(HexParser::Strict.decode(s), None); assert_eq!(HexParser::Strict.decode(s), None);
assert_eq!(HexParser::WhitespaceAllowed.decode(s), Some(vec![1, 171, 0, 255])); assert_eq!(
HexParser::WhitespaceAllowed.decode(s),
Some(vec![1, 171, 0, 255])
);
assert_eq!(HexParser::Liberal.decode(s), Some(vec![1, 171, 0, 255])); assert_eq!(HexParser::Liberal.decode(s), Some(vec![1, 171, 0, 255]));
} }
#[test] fn test_decode_liberal() { #[test]
fn test_decode_liberal() {
let s = "01ab zz 00ff"; let s = "01ab zz 00ff";
assert_eq!(HexParser::Strict.decode(s), None); assert_eq!(HexParser::Strict.decode(s), None);
assert_eq!(HexParser::WhitespaceAllowed.decode(s), None); assert_eq!(HexParser::WhitespaceAllowed.decode(s), None);
assert_eq!(HexParser::Liberal.decode(s), Some(vec![1, 171, 0, 255])); assert_eq!(HexParser::Liberal.decode(s), Some(vec![1, 171, 0, 255]));
} }
#[test] fn test_encode_lines() { #[test]
assert_eq!(HexFormatter::Lines(10).encode(&vec![0x5a; 11]), "5a5a5a5a5a\n5a5a5a5a5a\n5a"); fn test_encode_lines() {
assert_eq!(HexFormatter::Lines(10).encode(&vec![0x5a; 10]), "5a5a5a5a5a\n5a5a5a5a5a"); assert_eq!(
assert_eq!(HexFormatter::Lines(10).encode(&vec![0x5a; 9]), "5a5a5a5a5a\n5a5a5a5a"); HexFormatter::Lines(10).encode(&vec![0x5a; 11]),
assert_eq!(HexFormatter::Lines(9).encode(&vec![0x5a; 11]), "5a5a5a5a\n5a5a5a5a\n5a5a5a"); "5a5a5a5a5a\n5a5a5a5a5a\n5a"
assert_eq!(HexFormatter::Lines(9).encode(&vec![0x5a; 10]), "5a5a5a5a\n5a5a5a5a\n5a5a"); );
assert_eq!(HexFormatter::Lines(9).encode(&vec![0x5a; 9]), "5a5a5a5a\n5a5a5a5a\n5a"); assert_eq!(
assert_eq!(HexFormatter::Lines(8).encode(&vec![0x5a; 11]), "5a5a5a5a\n5a5a5a5a\n5a5a5a"); HexFormatter::Lines(10).encode(&vec![0x5a; 10]),
assert_eq!(HexFormatter::Lines(8).encode(&vec![0x5a; 10]), "5a5a5a5a\n5a5a5a5a\n5a5a"); "5a5a5a5a5a\n5a5a5a5a5a"
assert_eq!(HexFormatter::Lines(8).encode(&vec![0x5a; 9]), "5a5a5a5a\n5a5a5a5a\n5a"); );
assert_eq!(
HexFormatter::Lines(10).encode(&vec![0x5a; 9]),
"5a5a5a5a5a\n5a5a5a5a"
);
assert_eq!(
HexFormatter::Lines(9).encode(&vec![0x5a; 11]),
"5a5a5a5a\n5a5a5a5a\n5a5a5a"
);
assert_eq!(
HexFormatter::Lines(9).encode(&vec![0x5a; 10]),
"5a5a5a5a\n5a5a5a5a\n5a5a"
);
assert_eq!(
HexFormatter::Lines(9).encode(&vec![0x5a; 9]),
"5a5a5a5a\n5a5a5a5a\n5a"
);
assert_eq!(
HexFormatter::Lines(8).encode(&vec![0x5a; 11]),
"5a5a5a5a\n5a5a5a5a\n5a5a5a"
);
assert_eq!(
HexFormatter::Lines(8).encode(&vec![0x5a; 10]),
"5a5a5a5a\n5a5a5a5a\n5a5a"
);
assert_eq!(
HexFormatter::Lines(8).encode(&vec![0x5a; 9]),
"5a5a5a5a\n5a5a5a5a\n5a"
);
} }
#[test] fn test_encode_packed() { #[test]
assert_eq!(HexFormatter::Packed.encode(&vec![0x5a; 11]), "5a5a5a5a5a5a5a5a5a5a5a"); fn test_encode_packed() {
assert_eq!(HexFormatter::Packed.encode(&vec![0x5a; 10]), "5a5a5a5a5a5a5a5a5a5a"); assert_eq!(
assert_eq!(HexFormatter::Packed.encode(&vec![0x5a; 9]), "5a5a5a5a5a5a5a5a5a"); HexFormatter::Packed.encode(&vec![0x5a; 11]),
"5a5a5a5a5a5a5a5a5a5a5a"
);
assert_eq!(
HexFormatter::Packed.encode(&vec![0x5a; 10]),
"5a5a5a5a5a5a5a5a5a5a"
);
assert_eq!(
HexFormatter::Packed.encode(&vec![0x5a; 9]),
"5a5a5a5a5a5a5a5a5a"
);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
use serde::Serialize;
use super::value::IOValueDomainCodec;
use super::value::boundary as B; use super::value::boundary as B;
use super::value::writer::{Writer, CompoundWriter}; use super::value::writer::{CompoundWriter, Writer};
use super::value::IOValueDomainCodec;
use serde::Serialize;
pub use super::error::Error; pub use super::error::Error;
type Result<T> = std::result::Result<T, Error>; type Result<T> = std::result::Result<T, Error>;
@ -116,7 +116,10 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
Ok(self.write.end_record(c)?) Ok(self.write.end_record(c)?)
} }
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize { fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok>
where
T: Serialize,
{
let mut c = self.write.start_record(Some(1))?; let mut c = self.write.start_record(Some(1))?;
c.boundary(&B::start(B::Item::RecordLabel))?; c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("Some")?; c.write_symbol("Some")?;
@ -142,12 +145,12 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
Ok(self.write.end_record(c)?) Ok(self.write.end_record(c)?)
} }
fn serialize_unit_variant(self, fn serialize_unit_variant(
_name: &'static str, self,
_variant: u32, _name: &'static str,
variant_name: &'static str) -> _variant: u32,
Result<Self::Ok> variant_name: &'static str,
{ ) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(0))?; let mut c = self.write.start_record(Some(0))?;
c.boundary(&B::start(B::Item::RecordLabel))?; c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?; c.write_symbol(variant_name)?;
@ -155,8 +158,9 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
Ok(self.write.end_record(c)?) Ok(self.write.end_record(c)?)
} }
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<Self::Ok>
Result<Self::Ok> where T: Serialize where
T: Serialize,
{ {
match super::value::magic::receive_output_value(name, value) { match super::value::magic::receive_output_value(name, value) {
Some(v) => Ok(self.write.write(&mut IOValueDomainCodec, &v)?), Some(v) => Ok(self.write.write(&mut IOValueDomainCodec, &v)?),
@ -173,12 +177,15 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
} }
} }
fn serialize_newtype_variant<T: ?Sized>(self, fn serialize_newtype_variant<T: ?Sized>(
_name: &'static str, self,
_variant: u32, _name: &'static str,
variant_name: &'static str, _variant: u32,
value: &T) -> variant_name: &'static str,
Result<Self::Ok> where T: Serialize value: &T,
) -> Result<Self::Ok>
where
T: Serialize,
{ {
let mut c = self.write.start_record(Some(1))?; let mut c = self.write.start_record(Some(1))?;
c.boundary(&B::start(B::Item::RecordLabel))?; c.boundary(&B::start(B::Item::RecordLabel))?;
@ -201,22 +208,24 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
Ok(SerializeCompound::rec(self, c)) Ok(SerializeCompound::rec(self, c))
} }
fn serialize_tuple_struct(self, name: &'static str, count: usize) -> fn serialize_tuple_struct(
Result<Self::SerializeTupleStruct> self,
{ name: &'static str,
count: usize,
) -> Result<Self::SerializeTupleStruct> {
let mut c = self.write.start_record(Some(count))?; let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?; c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(name)?; c.write_symbol(name)?;
Ok(SerializeCompound::rec(self, c)) Ok(SerializeCompound::rec(self, c))
} }
fn serialize_tuple_variant(self, fn serialize_tuple_variant(
_name: &'static str, self,
_variant: u32, _name: &'static str,
variant_name: &'static str, _variant: u32,
count: usize) -> variant_name: &'static str,
Result<Self::SerializeTupleVariant> count: usize,
{ ) -> Result<Self::SerializeTupleVariant> {
let mut c = self.write.start_record(Some(count))?; let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?; c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?; c.write_symbol(variant_name)?;
@ -225,7 +234,11 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
fn serialize_map(self, count: Option<usize>) -> Result<Self::SerializeMap> { fn serialize_map(self, count: Option<usize>) -> Result<Self::SerializeMap> {
let d = self.write.start_dictionary(count)?; let d = self.write.start_dictionary(count)?;
Ok(SerializeDictionary { b: B::Type::default(), ser: self, d }) Ok(SerializeDictionary {
b: B::Type::default(),
ser: self,
d,
})
} }
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> { fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
@ -235,13 +248,13 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
Ok(SerializeCompound::rec(self, c)) Ok(SerializeCompound::rec(self, c))
} }
fn serialize_struct_variant(self, fn serialize_struct_variant(
_name: &'static str, self,
_variant: u32, _name: &'static str,
variant_name: &'static str, _variant: u32,
count: usize) -> variant_name: &'static str,
Result<Self::SerializeStructVariant> count: usize,
{ ) -> Result<Self::SerializeStructVariant> {
let mut c = self.write.start_record(Some(count))?; let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?; c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?; c.write_symbol(variant_name)?;
@ -253,7 +266,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'w,
type Ok = (); type Ok = ();
type Error = Error; type Error = Error;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize { fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>
where
T: Serialize,
{
self.b.opening = Some(B::Item::DictionaryKey); self.b.opening = Some(B::Item::DictionaryKey);
self.d.boundary(&self.b)?; self.d.boundary(&self.b)?;
to_writer(&mut self.d, key)?; to_writer(&mut self.d, key)?;
@ -261,7 +277,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'w,
Ok(()) Ok(())
} }
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: Serialize,
{
self.b.opening = Some(B::Item::DictionaryValue); self.b.opening = Some(B::Item::DictionaryValue);
self.d.boundary(&self.b)?; self.d.boundary(&self.b)?;
to_writer(&mut self.d, value)?; to_writer(&mut self.d, value)?;
@ -295,12 +314,19 @@ impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> {
} }
fn extend<T: ?Sized>(&mut self, value: &T) -> Result<()> fn extend<T: ?Sized>(&mut self, value: &T) -> Result<()>
where T: Serialize where
T: Serialize,
{ {
self.b.opening = Some(self.i.clone()); self.b.opening = Some(self.i.clone());
match &mut self.c { match &mut self.c {
SequenceVariant::Sequence(w) => { w.boundary(&self.b)?; to_writer(w, value)?; } SequenceVariant::Sequence(w) => {
SequenceVariant::Record(w) => { w.boundary(&self.b)?; to_writer(w, value)?; } w.boundary(&self.b)?;
to_writer(w, value)?;
}
SequenceVariant::Record(w) => {
w.boundary(&self.b)?;
to_writer(w, value)?;
}
} }
self.b.shift(None); self.b.shift(None);
Ok(()) Ok(())
@ -325,7 +351,8 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeStruct for SerializeCompound<'a, 'w
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()> fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize where
T: Serialize,
{ {
self.extend(value) self.extend(value)
} }
@ -340,7 +367,8 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeStructVariant for SerializeCompound
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()> fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize where
T: Serialize,
{ {
self.extend(value) self.extend(value)
} }
@ -354,7 +382,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeTuple for SerializeCompound<'a, 'w,
type Ok = (); type Ok = ();
type Error = Error; type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: Serialize,
{
self.extend(value) self.extend(value)
} }
@ -367,7 +398,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeTupleStruct for SerializeCompound<'
type Ok = (); type Ok = ();
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: Serialize,
{
self.extend(value) self.extend(value)
} }
@ -380,7 +414,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeTupleVariant for SerializeCompound<
type Ok = (); type Ok = ();
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: Serialize,
{
self.extend(value) self.extend(value)
} }
@ -393,7 +430,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeSeq for SerializeCompound<'a, 'w, W
type Ok = (); type Ok = ();
type Error = Error; type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: Serialize,
{
self.extend(value) self.extend(value)
} }

View File

@ -1,6 +1,6 @@
use crate::value::{self, to_value, IOValue, UnwrappedIOValue}; use crate::value::{self, to_value, IOValue, UnwrappedIOValue};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::iter::IntoIterator; use std::iter::IntoIterator;
use serde::{Serialize, Serializer, Deserialize, Deserializer};
pub fn serialize<S, T, Item>(s: T, serializer: S) -> Result<S::Ok, S::Error> pub fn serialize<S, T, Item>(s: T, serializer: S) -> Result<S::Ok, S::Error>
where where

View File

@ -4,26 +4,39 @@ use crate::value::{IOValue, NestedValue};
pub struct Symbol(pub String); pub struct Symbol(pub String);
impl serde::Serialize for Symbol { impl serde::Serialize for Symbol {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
IOValue::symbol(&self.0).serialize(serializer) IOValue::symbol(&self.0).serialize(serializer)
} }
} }
impl<'de> serde::Deserialize<'de> for Symbol { impl<'de> serde::Deserialize<'de> for Symbol {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let v = IOValue::deserialize(deserializer)?; let v = IOValue::deserialize(deserializer)?;
let s = v.value().as_symbol().ok_or_else(|| serde::de::Error::custom("Expected symbol"))?; let s = v
.value()
.as_symbol()
.ok_or_else(|| serde::de::Error::custom("Expected symbol"))?;
Ok(Symbol(s.clone())) Ok(Symbol(s.clone()))
} }
} }
pub fn serialize<S>(s: &str, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { pub fn serialize<S>(s: &str, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::Serialize; use serde::Serialize;
Symbol(s.to_string()).serialize(serializer) Symbol(s.to_string()).serialize(serializer)
} }
pub fn deserialize<'de, D>(deserializer: D) -> pub fn deserialize<'de, D>(deserializer: D) -> Result<String, D::Error>
Result<String, D::Error> where D: serde::Deserializer<'de> where
D: serde::Deserializer<'de>,
{ {
use serde::Deserialize; use serde::Deserialize;
Symbol::deserialize(deserializer).map(|v| v.0) Symbol::deserialize(deserializer).map(|v| v.0)

View File

@ -1,8 +1,8 @@
use crate::value::repr::{Float, Double};
use crate::value::{Value, NestedValue, IOValue, UnwrappedIOValue, Map};
use crate::error::{Error, ExpectedKind, Received}; use crate::error::{Error, ExpectedKind, Received};
use crate::value::repr::{Double, Float};
use crate::value::{IOValue, Map, NestedValue, UnwrappedIOValue, Value};
use serde::de::{DeserializeSeed, EnumAccess, MapAccess, SeqAccess, VariantAccess, Visitor};
use serde::Deserialize; use serde::Deserialize;
use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
use std::iter::Iterator; use std::iter::Iterator;
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;
@ -11,7 +11,9 @@ pub struct Deserializer<'de> {
input: &'de IOValue, input: &'de IOValue,
} }
pub fn from_value<'a, T>(v: &'a IOValue) -> Result<T> where T: Deserialize<'a> pub fn from_value<'a, T>(v: &'a IOValue) -> Result<T>
where
T: Deserialize<'a>,
{ {
let mut de = Deserializer::from_value(v); let mut de = Deserializer::from_value(v);
let t = T::deserialize(&mut de)?; let t = T::deserialize(&mut de)?;
@ -24,18 +26,21 @@ impl<'de> Deserializer<'de> {
} }
fn check<'a, T, F>(&'a mut self, f: F, k: ExpectedKind) -> Result<T> fn check<'a, T, F>(&'a mut self, f: F, k: ExpectedKind) -> Result<T>
where F: FnOnce(&'de UnwrappedIOValue) -> Option<T> where
F: FnOnce(&'de UnwrappedIOValue) -> Option<T>,
{ {
f(self.input.value()).ok_or_else( f(self.input.value()).ok_or_else(|| {
|| Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", self.input)))) Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", self.input)))
})
} }
} }
impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de> impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de> {
{
type Error = Error; type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
let v = self.input.value(); let v = self.input.value();
match v { match v {
@ -44,18 +49,23 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
Value::Double(Double(d)) => visitor.visit_f64(*d), Value::Double(Double(d)) => visitor.visit_f64(*d),
Value::String(ref s) => visitor.visit_str(&s), Value::String(ref s) => visitor.visit_str(&s),
Value::ByteString(_) => self.deserialize_bytes(visitor), Value::ByteString(_) => self.deserialize_bytes(visitor),
Value::Record(_) => Value::Record(_) => {
if v.is_simple_record("tuple", Some(0)) { if v.is_simple_record("tuple", Some(0)) {
self.deserialize_unit(visitor) self.deserialize_unit(visitor)
} else if v.is_simple_record("UnicodeScalar", Some(1)) { } else if v.is_simple_record("UnicodeScalar", Some(1)) {
self.deserialize_char(visitor) self.deserialize_char(visitor)
} else if v.is_simple_record("None", Some(0)) || v.is_simple_record("Some", Some(1)) { } else if v.is_simple_record("None", Some(0)) || v.is_simple_record("Some", Some(1))
{
self.deserialize_option(visitor) self.deserialize_option(visitor)
} else if v.is_simple_record("tuple", None) { } else if v.is_simple_record("tuple", None) {
visitor.visit_seq(VecSeq::new(self, v.as_simple_record("tuple", None).unwrap().iter())) visitor.visit_seq(VecSeq::new(
self,
v.as_simple_record("tuple", None).unwrap().iter(),
))
} else { } else {
Err(Error::CannotDeserializeAny) Err(Error::CannotDeserializeAny)
} }
}
Value::Sequence(ref v) => visitor.visit_seq(VecSeq::new(self, v.iter())), Value::Sequence(ref v) => visitor.visit_seq(VecSeq::new(self, v.iter())),
Value::Dictionary(ref d) => visitor.visit_map(DictMap::new(self, d)), Value::Dictionary(ref d) => visitor.visit_map(DictMap::new(self, d)),
_ => match v.as_i64() { _ => match v.as_i64() {
@ -65,58 +75,78 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
None => match v.as_signedinteger() { None => match v.as_signedinteger() {
Some(n) => Err(Error::NumberOutOfRange(n.into())), Some(n) => Err(Error::NumberOutOfRange(n.into())),
None => Err(Error::CannotDeserializeAny), None => Err(Error::CannotDeserializeAny),
} },
} },
} },
} }
} }
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_bool(self.input.value().to_boolean()?) visitor.visit_bool(self.input.value().to_boolean()?)
} }
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_i8(self.input.value().to_i8()?) visitor.visit_i8(self.input.value().to_i8()?)
} }
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_i16(self.input.value().to_i16()?) visitor.visit_i16(self.input.value().to_i16()?)
} }
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_i32(self.input.value().to_i32()?) visitor.visit_i32(self.input.value().to_i32()?)
} }
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_i64(self.input.value().to_i64()?) visitor.visit_i64(self.input.value().to_i64()?)
} }
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_u8(self.input.value().to_u8()?) visitor.visit_u8(self.input.value().to_u8()?)
} }
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_u16(self.input.value().to_u16()?) visitor.visit_u16(self.input.value().to_u16()?)
} }
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_u32(self.input.value().to_u32()?) visitor.visit_u32(self.input.value().to_u32()?)
} }
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_u64(self.input.value().to_u64()?) visitor.visit_u64(self.input.value().to_u64()?)
} }
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
match self.input.value().as_f64() { match self.input.value().as_f64() {
Some(d) => visitor.visit_f32(d as f32), Some(d) => visitor.visit_f32(d as f32),
@ -124,7 +154,9 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
} }
} }
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
match self.input.value().as_f32() { match self.input.value().as_f32() {
Some(f) => visitor.visit_f64(f as f64), Some(f) => visitor.visit_f64(f as f64),
@ -132,34 +164,46 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
} }
} }
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_char(self.input.value().to_char()?) visitor.visit_char(self.input.value().to_char()?)
} }
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
let s: &'de str = &self.input.value().to_string()?; let s: &'de str = &self.input.value().to_string()?;
visitor.visit_borrowed_str(s) visitor.visit_borrowed_str(s)
} }
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
self.deserialize_str(visitor) self.deserialize_str(visitor)
} }
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
let bs: &'de [u8] = &self.input.value().to_bytestring()?; let bs: &'de [u8] = &self.input.value().to_bytestring()?;
visitor.visit_borrowed_bytes(bs) visitor.visit_borrowed_bytes(bs)
} }
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_byte_buf(self.input.value().to_bytestring()?.clone()) visitor.visit_byte_buf(self.input.value().to_bytestring()?.clone())
} }
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
match self.input.value().to_option()? { match self.input.value().to_option()? {
None => visitor.visit_none(), None => visitor.visit_none(),
@ -170,21 +214,25 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
} }
} }
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
let _fs = self.input.value().to_simple_record("tuple", Some(0))?; let _fs = self.input.value().to_simple_record("tuple", Some(0))?;
visitor.visit_unit() visitor.visit_unit()
} }
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
-> Result<V::Value> where V: Visitor<'de> where
V: Visitor<'de>,
{ {
let _fs = self.input.value().to_simple_record(name, Some(0))?; let _fs = self.input.value().to_simple_record(name, Some(0))?;
visitor.visit_unit() visitor.visit_unit()
} }
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
-> Result<V::Value> where V: Visitor<'de> where
V: Visitor<'de>,
{ {
match super::magic::transmit_input_value(name, || Ok(self.input.clone()))? { match super::magic::transmit_input_value(name, || Ok(self.input.clone()))? {
Some(v) => visitor.visit_u64(v), Some(v) => visitor.visit_u64(v),
@ -196,7 +244,10 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
} }
} }
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> { fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
match self.input.value().as_sequence() { match self.input.value().as_sequence() {
Some(vs) => visitor.visit_seq(VecSeq::new(self, vs.iter())), Some(vs) => visitor.visit_seq(VecSeq::new(self, vs.iter())),
None => { None => {
@ -208,49 +259,73 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
} }
} }
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
let fs = self.input.value().to_simple_record("tuple", Some(len))?; let fs = self.input.value().to_simple_record("tuple", Some(len))?;
visitor.visit_seq(VecSeq::new(self, fs.iter())) visitor.visit_seq(VecSeq::new(self, fs.iter()))
} }
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) fn deserialize_tuple_struct<V>(
-> Result<V::Value> where V: Visitor<'de> self,
name: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
let fs = self.input.value().to_simple_record(name, Some(len))?; let fs = self.input.value().to_simple_record(name, Some(len))?;
visitor.visit_seq(VecSeq::new(self, fs.iter())) visitor.visit_seq(VecSeq::new(self, fs.iter()))
} }
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> { fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let d = self.input.value().to_dictionary()?; let d = self.input.value().to_dictionary()?;
visitor.visit_map(DictMap::new(self, d)) visitor.visit_map(DictMap::new(self, d))
} }
fn deserialize_struct<V>(self, fn deserialize_struct<V>(
name: &'static str, self,
fields: &'static [&'static str], name: &'static str,
visitor: V) fields: &'static [&'static str],
-> Result<V::Value> where V: Visitor<'de> visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
let fs = self.input.value().to_simple_record(name, Some(fields.len()))?; let fs = self
.input
.value()
.to_simple_record(name, Some(fields.len()))?;
visitor.visit_seq(VecSeq::new(self, fs.iter())) visitor.visit_seq(VecSeq::new(self, fs.iter()))
} }
fn deserialize_enum<V>(self, fn deserialize_enum<V>(
_name: &'static str, self,
_variants: &'static [&'static str], _name: &'static str,
visitor: V) _variants: &'static [&'static str],
-> Result<V::Value> where V: Visitor<'de> visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_enum(self) visitor.visit_enum(self)
} }
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_str(&self.input.value().to_symbol()?) visitor.visit_str(&self.input.value().to_symbol()?)
} }
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{ {
visitor.visit_none() visitor.visit_none()
} }
@ -270,10 +345,9 @@ impl<'de, 'a, I: Iterator<Item = &'de IOValue>> VecSeq<'a, 'de, I> {
impl<'de, 'a, I: Iterator<Item = &'de IOValue>> SeqAccess<'de> for VecSeq<'a, 'de, I> { impl<'de, 'a, I: Iterator<Item = &'de IOValue>> SeqAccess<'de> for VecSeq<'a, 'de, I> {
type Error = Error; type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
Result<Option<T::Value>>
where where
T: DeserializeSeed<'de> T: DeserializeSeed<'de>,
{ {
match self.iter.next() { match self.iter.next() {
None => Ok(None), None => Ok(None),
@ -293,15 +367,20 @@ pub struct DictMap<'a, 'de: 'a> {
impl<'de, 'a> DictMap<'a, 'de> { impl<'de, 'a> DictMap<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>, d: &'de Map<IOValue, IOValue>) -> Self { fn new(de: &'a mut Deserializer<'de>, d: &'de Map<IOValue, IOValue>) -> Self {
DictMap{ pending: None, iter: Box::new(d.iter()), de } DictMap {
pending: None,
iter: Box::new(d.iter()),
de,
}
} }
} }
impl<'de, 'a> MapAccess<'de> for DictMap<'a, 'de> { impl<'de, 'a> MapAccess<'de> for DictMap<'a, 'de> {
type Error = Error; type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
-> Result<Option<K::Value>> where K: DeserializeSeed<'de> where
K: DeserializeSeed<'de>,
{ {
match self.iter.next() { match self.iter.next() {
None => Ok(None), None => Ok(None),
@ -313,7 +392,10 @@ impl<'de, 'a> MapAccess<'de> for DictMap<'a, 'de> {
} }
} }
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value> where V: DeserializeSeed<'de> { fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where
V: DeserializeSeed<'de>,
{
let v = self.pending.unwrap(); let v = self.pending.unwrap();
self.pending = None; self.pending = None;
self.de.input = v; self.de.input = v;
@ -325,8 +407,9 @@ impl<'a, 'de> EnumAccess<'de> for &'a mut Deserializer<'de> {
type Error = Error; type Error = Error;
type Variant = Self; type Variant = Self;
fn variant_seed<V>(self, seed: V) fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de> where
V: DeserializeSeed<'de>,
{ {
let r = self.check(|v| v.as_record(None), ExpectedKind::Record(None))?; let r = self.check(|v| v.as_record(None), ExpectedKind::Record(None))?;
let v = self.input; let v = self.input;
@ -344,19 +427,37 @@ impl<'a, 'de> VariantAccess<'de> for &'a mut Deserializer<'de> {
Ok(()) Ok(())
} }
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> where T: DeserializeSeed<'de> { fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
where
T: DeserializeSeed<'de>,
{
let r = self.check(|v| v.as_record(Some(1)), ExpectedKind::Record(Some(1)))?; let r = self.check(|v| v.as_record(Some(1)), ExpectedKind::Record(Some(1)))?;
self.input = &r.fields()[0]; self.input = &r.fields()[0];
seed.deserialize(&mut *self) seed.deserialize(&mut *self)
} }
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de> { fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
visitor.visit_seq(VecSeq::new(self, self.input.value().as_record(None).unwrap().fields().iter())) where
V: Visitor<'de>,
{
visitor.visit_seq(VecSeq::new(
self,
self.input.value().as_record(None).unwrap().fields().iter(),
))
} }
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
-> Result<V::Value> where V: Visitor<'de> where
V: Visitor<'de>,
{ {
visitor.visit_seq(VecSeq::new(self, self.input.value().as_record(Some(fields.len())).unwrap().fields().iter())) visitor.visit_seq(VecSeq::new(
self,
self.input
.value()
.as_record(Some(fields.len()))
.unwrap()
.fields()
.iter(),
))
} }
} }

View File

@ -1,5 +1,6 @@
use std::io; use std::io;
use super::packed;
use super::BinarySource; use super::BinarySource;
use super::BytesBinarySource; use super::BytesBinarySource;
use super::Embeddable; use super::Embeddable;
@ -7,13 +8,9 @@ use super::IOValue;
use super::NestedValue; use super::NestedValue;
use super::Reader; use super::Reader;
use super::Writer; use super::Writer;
use super::packed;
pub trait DomainParse<D: Embeddable> { pub trait DomainParse<D: Embeddable> {
fn parse_embedded( fn parse_embedded(&mut self, v: &IOValue) -> io::Result<D>;
&mut self,
v: &IOValue,
) -> io::Result<D>;
} }
pub trait DomainDecode<D: Embeddable> { pub trait DomainDecode<D: Embeddable> {
@ -25,18 +22,11 @@ pub trait DomainDecode<D: Embeddable> {
} }
pub trait DomainEncode<D: Embeddable> { pub trait DomainEncode<D: Embeddable> {
fn encode_embedded<W: Writer>( fn encode_embedded<W: Writer>(&mut self, w: &mut W, d: &D) -> io::Result<()>;
&mut self,
w: &mut W,
d: &D,
) -> io::Result<()>;
} }
impl<'a, D: Embeddable, T: DomainParse<D>> DomainParse<D> for &'a mut T { impl<'a, D: Embeddable, T: DomainParse<D>> DomainParse<D> for &'a mut T {
fn parse_embedded( fn parse_embedded(&mut self, v: &IOValue) -> io::Result<D> {
&mut self,
v: &IOValue,
) -> io::Result<D> {
(**self).parse_embedded(v) (**self).parse_embedded(v)
} }
} }
@ -61,7 +51,9 @@ impl<D: Embeddable> DomainEncode<D> for DebugDomainEncode {
pub struct FromStrDomainParse; pub struct FromStrDomainParse;
impl<Err: Into<io::Error>, D: Embeddable + std::str::FromStr<Err = Err>> DomainParse<D> for FromStrDomainParse { impl<Err: Into<io::Error>, D: Embeddable + std::str::FromStr<Err = Err>> DomainParse<D>
for FromStrDomainParse
{
fn parse_embedded(&mut self, v: &IOValue) -> io::Result<D> { fn parse_embedded(&mut self, v: &IOValue) -> io::Result<D> {
Ok(D::from_str(v.value().to_string()?).map_err(|e| e.into())?) Ok(D::from_str(v.value().to_string()?).map_err(|e| e.into())?)
} }
@ -80,11 +72,7 @@ impl DomainDecode<IOValue> for IOValueDomainCodec {
} }
impl DomainEncode<IOValue> for IOValueDomainCodec { impl DomainEncode<IOValue> for IOValueDomainCodec {
fn encode_embedded<W: Writer>( fn encode_embedded<W: Writer>(&mut self, w: &mut W, d: &IOValue) -> io::Result<()> {
&mut self,
w: &mut W,
d: &IOValue,
) -> io::Result<()> {
w.write(self, d) w.write(self, d)
} }
} }
@ -97,17 +85,19 @@ impl<D: Embeddable> DomainDecode<D> for NoEmbeddedDomainCodec {
_src: &'src mut S, _src: &'src mut S,
_read_annotations: bool, _read_annotations: bool,
) -> io::Result<D> { ) -> io::Result<D> {
Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here")) Err(io::Error::new(
io::ErrorKind::Unsupported,
"Embedded values not supported here",
))
} }
} }
impl<D: Embeddable> DomainEncode<D> for NoEmbeddedDomainCodec { impl<D: Embeddable> DomainEncode<D> for NoEmbeddedDomainCodec {
fn encode_embedded<W: Writer>( fn encode_embedded<W: Writer>(&mut self, _w: &mut W, _d: &D) -> io::Result<()> {
&mut self, Err(io::Error::new(
_w: &mut W, io::ErrorKind::Unsupported,
_d: &D, "Embedded values not supported here",
) -> io::Result<()> { ))
Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))
} }
} }
@ -120,12 +110,10 @@ impl<C> ViaCodec<C> {
} }
impl<D: Embeddable, C: DomainDecode<D>> DomainParse<D> for ViaCodec<C> { impl<D: Embeddable, C: DomainDecode<D>> DomainParse<D> for ViaCodec<C> {
fn parse_embedded( fn parse_embedded(&mut self, v: &IOValue) -> io::Result<D> {
&mut self,
v: &IOValue,
) -> io::Result<D> {
let bs = packed::PackedWriter::encode_iovalue(v)?; let bs = packed::PackedWriter::encode_iovalue(v)?;
self.0.decode_embedded(&mut BytesBinarySource::new(&bs), true) self.0
.decode_embedded(&mut BytesBinarySource::new(&bs), true)
} }
} }
@ -135,7 +123,9 @@ impl<D: Embeddable, C: DomainParse<D>> DomainDecode<D> for ViaCodec<C> {
src: &'src mut S, src: &'src mut S,
read_annotations: bool, read_annotations: bool,
) -> io::Result<D> { ) -> io::Result<D> {
let v = src.packed(IOValueDomainCodec).demand_next(read_annotations)?; let v = src
.packed(IOValueDomainCodec)
.demand_next(read_annotations)?;
self.0.parse_embedded(&v) self.0.parse_embedded(&v)
} }
} }

View File

@ -8,22 +8,22 @@ impl<'de> serde::de::Visitor<'de> for IOValueVisitor {
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "a magic encoding of an embedded Preserves Value") write!(formatter, "a magic encoding of an embedded Preserves Value")
} }
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> where E: serde::de::Error { fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let b = unsafe { Box::from_raw(v as *mut IOValue) }; let b = unsafe { Box::from_raw(v as *mut IOValue) };
Ok(*b) Ok(*b)
} }
} }
#[inline(always)] #[inline(always)]
pub fn output_value<S: serde::Serializer>(serializer: S, v: IOValue) -> pub fn output_value<S: serde::Serializer>(serializer: S, v: IOValue) -> Result<S::Ok, S::Error> {
Result<S::Ok, S::Error>
{
serializer.serialize_newtype_struct(MAGIC, &(Box::into_raw(Box::new(v)) as u64)) serializer.serialize_newtype_struct(MAGIC, &(Box::into_raw(Box::new(v)) as u64))
} }
#[inline(always)] #[inline(always)]
pub fn input_value<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<IOValue, D::Error> pub fn input_value<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<IOValue, D::Error> {
{
deserializer.deserialize_newtype_struct(MAGIC, IOValueVisitor) deserializer.deserialize_newtype_struct(MAGIC, IOValueVisitor)
} }
@ -32,7 +32,8 @@ pub fn input_value<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<
#[inline] #[inline]
pub fn receive_output_value<T: ?Sized>(name: &'static str, magic_value: &T) -> Option<IOValue> { pub fn receive_output_value<T: ?Sized>(name: &'static str, magic_value: &T) -> Option<IOValue> {
if name == MAGIC { if name == MAGIC {
let b = unsafe { Box::from_raw(*((magic_value as *const T) as *const u64) as *mut IOValue) }; let b =
unsafe { Box::from_raw(*((magic_value as *const T) as *const u64) as *mut IOValue) };
let v: IOValue = *b; let v: IOValue = *b;
Some(v) Some(v)
} else { } else {
@ -42,7 +43,8 @@ pub fn receive_output_value<T: ?Sized>(name: &'static str, magic_value: &T) -> O
#[inline] #[inline]
pub fn transmit_input_value<F>(name: &'static str, f: F) -> Result<Option<u64>, crate::error::Error> pub fn transmit_input_value<F>(name: &'static str, f: F) -> Result<Option<u64>, crate::error::Error>
where F: FnOnce() -> Result<IOValue, crate::error::Error> where
F: FnOnce() -> Result<IOValue, crate::error::Error>,
{ {
if name == MAGIC { if name == MAGIC {
let b: Box<IOValue> = Box::new(f()?); let b: Box<IOValue> = Box::new(f()?);

View File

@ -24,19 +24,23 @@ pub fn merge2<N: NestedValue>(v: N, w: N) -> Option<N> {
Some(N::wrap(v_anns, v_val)) Some(N::wrap(v_anns, v_val))
} else { } else {
let maybe_merged = match v_val { let maybe_merged = match v_val {
Value::Record(rv) => Value::Record(rv) => Some(Value::Record(Record(merge_seqs(
Some(Value::Record(Record(merge_seqs(rv.0, w_val.into_record()?.0)?))), rv.0,
Value::Sequence(vs) => w_val.into_record()?.0,
Some(Value::Sequence(merge_seqs(vs, w_val.into_sequence()?)?)), )?))),
Value::Set(_vs) => Value::Sequence(vs) => Some(Value::Sequence(merge_seqs(vs, w_val.into_sequence()?)?)),
None, // unsure how to merge sets Value::Set(_vs) => None, // unsure how to merge sets
Value::Dictionary(vs) => { Value::Dictionary(vs) => {
let mut ws = w_val.into_dictionary()?; let mut ws = w_val.into_dictionary()?;
let mut rs = Map::new(); let mut rs = Map::new();
for (k, vv) in vs.into_iter() { for (k, vv) in vs.into_iter() {
match ws.remove(&k) { match ws.remove(&k) {
Some(wv) => { rs.insert(k, merge2(vv, wv)?); } Some(wv) => {
None => { rs.insert(k, vv); } rs.insert(k, merge2(vv, wv)?);
}
None => {
rs.insert(k, vv);
}
} }
} }
rs.extend(ws.into_iter()); rs.extend(ws.into_iter());

View File

@ -2,6 +2,7 @@ pub mod boundary;
pub mod de; pub mod de;
pub mod domain; pub mod domain;
pub mod magic; pub mod magic;
pub mod merge;
pub mod packed; pub mod packed;
pub mod reader; pub mod reader;
pub mod repr; pub mod repr;
@ -10,14 +11,13 @@ pub mod signed_integer;
pub mod suspendable; pub mod suspendable;
pub mod text; pub mod text;
pub mod writer; pub mod writer;
pub mod merge;
pub use de::Deserializer;
pub use de::from_value; pub use de::from_value;
pub use de::Deserializer;
pub use domain::DebugDomainEncode;
pub use domain::DomainDecode; pub use domain::DomainDecode;
pub use domain::DomainEncode; pub use domain::DomainEncode;
pub use domain::DomainParse; pub use domain::DomainParse;
pub use domain::DebugDomainEncode;
pub use domain::FromStrDomainParse; pub use domain::FromStrDomainParse;
pub use domain::IOValueDomainCodec; pub use domain::IOValueDomainCodec;
pub use domain::NoEmbeddedDomainCodec; pub use domain::NoEmbeddedDomainCodec;
@ -50,14 +50,16 @@ pub use repr::Set;
pub use repr::UnwrappedIOValue; pub use repr::UnwrappedIOValue;
pub use repr::Value; pub use repr::Value;
pub use repr::ValueClass; pub use repr::ValueClass;
pub use ser::Serializer;
pub use ser::to_value; pub use ser::to_value;
pub use ser::Serializer;
pub use text::TextReader; pub use text::TextReader;
pub use text::TextWriter; pub use text::TextWriter;
pub use writer::Writer; pub use writer::Writer;
pub fn invert_map<A, B>(m: &Map<A, B>) -> Map<B, A> pub fn invert_map<A, B>(m: &Map<A, B>) -> Map<B, A>
where A: Clone, B: Clone + Ord where
A: Clone,
B: Clone + Ord,
{ {
m.iter().map(|(a, b)| (b.clone(), a.clone())).collect() m.iter().map(|(a, b)| (b.clone(), a.clone())).collect()
} }

View File

@ -1,4 +1,4 @@
use std::convert::{TryFrom, From}; use std::convert::{From, TryFrom};
use std::io; use std::io;
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
@ -27,7 +27,10 @@ pub struct InvalidTag(u8);
impl From<InvalidTag> for io::Error { impl From<InvalidTag> for io::Error {
fn from(v: InvalidTag) -> Self { fn from(v: InvalidTag) -> Self {
io::Error::new(io::ErrorKind::InvalidData, format!("Invalid Preserves tag {}", v.0)) io::Error::new(
io::ErrorKind::InvalidData,
format!("Invalid Preserves tag {}", v.0),
)
} }
} }
@ -59,7 +62,7 @@ impl TryFrom<u8> for Tag {
0xb5 => Ok(Self::Sequence), 0xb5 => Ok(Self::Sequence),
0xb6 => Ok(Self::Set), 0xb6 => Ok(Self::Set),
0xb7 => Ok(Self::Dictionary), 0xb7 => Ok(Self::Dictionary),
_ => Err(InvalidTag(v)) _ => Err(InvalidTag(v)),
} }
} }
} }
@ -74,7 +77,13 @@ impl From<Tag> for u8 {
Tag::End => 0x84, Tag::End => 0x84,
Tag::Annotation => 0x85, Tag::Annotation => 0x85,
Tag::Embedded => 0x86, Tag::Embedded => 0x86,
Tag::SmallInteger(v) => if v < 0 { (v + 16) as u8 + 0x90 } else { v as u8 + 0x90 }, Tag::SmallInteger(v) => {
if v < 0 {
(v + 16) as u8 + 0x90
} else {
v as u8 + 0x90
}
}
Tag::MediumInteger(count) => count - 1 + 0xa0, Tag::MediumInteger(count) => count - 1 + 0xa0,
Tag::SignedInteger => 0xb0, Tag::SignedInteger => 0xb0,
Tag::String => 0xb1, Tag::String => 0xb1,

View File

@ -13,7 +13,9 @@ pub fn from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &[u8], bs: &[u8],
decode_embedded: Dec, decode_embedded: Dec,
) -> io::Result<N> { ) -> io::Result<N> {
super::BytesBinarySource::new(bs).packed(decode_embedded).demand_next(false) super::BytesBinarySource::new(bs)
.packed(decode_embedded)
.demand_next(false)
} }
pub fn iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> { pub fn iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
@ -24,7 +26,9 @@ pub fn annotated_from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &[u8], bs: &[u8],
decode_embedded: Dec, decode_embedded: Dec,
) -> io::Result<N> { ) -> io::Result<N> {
super::BytesBinarySource::new(bs).packed(decode_embedded).demand_next(true) super::BytesBinarySource::new(bs)
.packed(decode_embedded)
.demand_next(true)
} }
pub fn annotated_iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> { pub fn annotated_iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {

View File

@ -1,4 +1,4 @@
use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_syntax_error}; use crate::error::{self, io_syntax_error, is_eof_io_error, ExpectedKind, Received};
use num::bigint::BigInt; use num::bigint::BigInt;
use num::traits::cast::{FromPrimitive, ToPrimitive}; use num::traits::cast::{FromPrimitive, ToPrimitive};
@ -9,36 +9,29 @@ use std::convert::TryInto;
use std::io; use std::io;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::constants::Tag;
use super::super::{ use super::super::{
CompoundClass,
DomainDecode,
Map,
NestedValue,
Record,
Set,
Value,
boundary as B, boundary as B,
reader::{ reader::{BinarySource, Reader, ReaderResult, Token},
Token,
BinarySource,
Reader,
ReaderResult,
},
repr::Annotations, repr::Annotations,
signed_integer::SignedInteger, signed_integer::SignedInteger,
CompoundClass, DomainDecode, Map, NestedValue, Record, Set, Value,
}; };
use super::constants::Tag;
pub struct PackedReader<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> { pub struct PackedReader<
'de,
'src,
N: NestedValue,
Dec: DomainDecode<N::Embedded>,
S: BinarySource<'de>,
> {
pub source: &'src mut S, pub source: &'src mut S,
pub decode_embedded: Dec, pub decode_embedded: Dec,
phantom: PhantomData<&'de N>, phantom: PhantomData<&'de N>,
} }
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>>
BinarySource<'de> BinarySource<'de> for PackedReader<'de, 'src, N, Dec, S>
for PackedReader<'de, 'src, N, Dec, S>
{ {
type Mark = S::Mark; type Mark = S::Mark;
#[inline(always)] #[inline(always)]
@ -71,10 +64,16 @@ fn out_of_range<I: Into<BigInt>>(i: I) -> error::Error {
error::Error::NumberOutOfRange(i.into()) error::Error::NumberOutOfRange(i.into())
} }
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> PackedReader<'de, 'src, N, Dec, S> { impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>>
PackedReader<'de, 'src, N, Dec, S>
{
#[inline(always)] #[inline(always)]
pub fn new(source: &'src mut S, decode_embedded: Dec) -> Self { pub fn new(source: &'src mut S, decode_embedded: Dec) -> Self {
PackedReader { source, decode_embedded, phantom: PhantomData } PackedReader {
source,
decode_embedded,
phantom: PhantomData,
}
} }
#[inline(always)] #[inline(always)]
@ -87,7 +86,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
fn expected(&mut self, k: ExpectedKind) -> error::Error { fn expected(&mut self, k: ExpectedKind) -> error::Error {
match self.demand_next(true) { match self.demand_next(true) {
Ok(v) => error::Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))), Ok(v) => error::Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))),
Err(e) => e.into() Err(e) => e.into(),
} }
} }
@ -99,7 +98,9 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
let v = self.read()?; let v = self.read()?;
acc |= ((v & 0x7f) as usize) << shift; acc |= ((v & 0x7f) as usize) << shift;
shift += 7; shift += 7;
if v & 0x80 == 0 { return Ok(acc) } if v & 0x80 == 0 {
return Ok(acc);
}
} }
} }
@ -120,7 +121,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
Tag::Annotation => { Tag::Annotation => {
self.skip()?; self.skip()?;
self.skip_value()?; self.skip_value()?;
}, }
other => return Ok(other), other => return Ok(other),
} }
} }
@ -137,8 +138,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
} }
} }
fn next_compound(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<()> fn next_compound(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<()> {
{
let actual_tag = self.peek_next_nonannotation_tag()?; let actual_tag = self.peek_next_nonannotation_tag()?;
if actual_tag == expected_tag { if actual_tag == expected_tag {
self.skip()?; self.skip()?;
@ -159,20 +159,33 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
if (bs[0] & 0x80) == 0 { if (bs[0] & 0x80) == 0 {
// Positive or zero. // Positive or zero.
let mut i = 0; let mut i = 0;
while i < count && bs[i] == 0 { i += 1; } while i < count && bs[i] == 0 {
i += 1;
}
if count - i <= 16 { if count - i <= 16 {
Ok(SignedInteger::from(u128::from_be_bytes(bs[bs.len() - 16..].try_into().unwrap()))) Ok(SignedInteger::from(u128::from_be_bytes(
bs[bs.len() - 16..].try_into().unwrap(),
)))
} else { } else {
Ok(SignedInteger::from(Cow::Owned(BigInt::from_bytes_be(num::bigint::Sign::Plus, &bs[i..])))) Ok(SignedInteger::from(Cow::Owned(BigInt::from_bytes_be(
num::bigint::Sign::Plus,
&bs[i..],
))))
} }
} else { } else {
// Negative. // Negative.
let mut i = 0; let mut i = 0;
while i < count && bs[i] == 0xff { i += 1; } while i < count && bs[i] == 0xff {
i += 1;
}
if count - i <= 16 { if count - i <= 16 {
Ok(SignedInteger::from(i128::from_be_bytes(bs[bs.len() - 16..].try_into().unwrap()))) Ok(SignedInteger::from(i128::from_be_bytes(
bs[bs.len() - 16..].try_into().unwrap(),
)))
} else { } else {
Ok(SignedInteger::from(Cow::Owned(BigInt::from_signed_bytes_be(&bs)))) Ok(SignedInteger::from(Cow::Owned(
BigInt::from_signed_bytes_be(&bs),
)))
} }
} }
} else { } else {
@ -188,7 +201,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
#[inline(always)] #[inline(always)]
fn next_unsigned<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T> fn next_unsigned<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T>
where where
F: FnOnce(u128) -> Option<T> F: FnOnce(u128) -> Option<T>,
{ {
let tag = self.peek_next_nonannotation_tag()?; let tag = self.peek_next_nonannotation_tag()?;
match tag { match tag {
@ -213,14 +226,14 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
let i = n.try_into().map_err(|_| out_of_range(n))?; let i = n.try_into().map_err(|_| out_of_range(n))?;
f(i).ok_or_else(|| out_of_range(i)) f(i).ok_or_else(|| out_of_range(i))
} }
_ => Err(self.expected(ExpectedKind::SignedInteger)) _ => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
#[inline(always)] #[inline(always)]
fn next_signed<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T> fn next_signed<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T>
where where
F: FnOnce(i128) -> Option<T> F: FnOnce(i128) -> Option<T>,
{ {
let tag = self.peek_next_nonannotation_tag()?; let tag = self.peek_next_nonannotation_tag()?;
match tag { match tag {
@ -241,7 +254,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
let i = n.try_into().map_err(|_| out_of_range(n))?; let i = n.try_into().map_err(|_| out_of_range(n))?;
f(i).ok_or_else(|| out_of_range(i)) f(i).ok_or_else(|| out_of_range(i))
} }
_ => Err(self.expected(ExpectedKind::SignedInteger)) _ => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -271,8 +284,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
} }
} }
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> Reader<'de, N>
Reader<'de, N>
for PackedReader<'de, 'src, N, Dec, S> for PackedReader<'de, 'src, N, Dec, S>
{ {
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> { fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
@ -305,9 +317,11 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
self.demand_next(read_annotations)? self.demand_next(read_annotations)?
} }
} }
Tag::Embedded => { Tag::Embedded => Value::Embedded(
Value::Embedded(self.decode_embedded.decode_embedded(self.source, read_annotations)?).wrap() self.decode_embedded
} .decode_embedded(self.source, read_annotations)?,
)
.wrap(),
Tag::SmallInteger(v) => { Tag::SmallInteger(v) => {
// TODO: prebuild these in value.rs // TODO: prebuild these in value.rs
Value::from(v).wrap() Value::from(v).wrap()
@ -335,27 +349,35 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
} }
Tag::Record => { Tag::Record => {
let mut vs = Vec::new(); let mut vs = Vec::new();
while let Some(v) = self.next_upto_end(read_annotations)? { vs.push(v); } while let Some(v) = self.next_upto_end(read_annotations)? {
vs.push(v);
}
if vs.is_empty() { if vs.is_empty() {
return Err(io_syntax_error("Too few elements in encoded record")) return Err(io_syntax_error("Too few elements in encoded record"));
} }
Value::Record(Record(vs)).wrap() Value::Record(Record(vs)).wrap()
} }
Tag::Sequence => { Tag::Sequence => {
let mut vs = Vec::new(); let mut vs = Vec::new();
while let Some(v) = self.next_upto_end(read_annotations)? { vs.push(v); } while let Some(v) = self.next_upto_end(read_annotations)? {
vs.push(v);
}
Value::Sequence(vs).wrap() Value::Sequence(vs).wrap()
} }
Tag::Set => { Tag::Set => {
let mut s = Set::new(); let mut s = Set::new();
while let Some(v) = self.next_upto_end(read_annotations)? { s.insert(v); } while let Some(v) = self.next_upto_end(read_annotations)? {
s.insert(v);
}
Value::Set(s).wrap() Value::Set(s).wrap()
} }
Tag::Dictionary => { Tag::Dictionary => {
let mut d = Map::new(); let mut d = Map::new();
while let Some(k) = self.next_upto_end(read_annotations)? { while let Some(k) = self.next_upto_end(read_annotations)? {
match self.next_upto_end(read_annotations)? { match self.next_upto_end(read_annotations)? {
Some(v) => { d.insert(k, v); } Some(v) => {
d.insert(k, v);
}
None => return Err(io_syntax_error("Missing dictionary value")), None => return Err(io_syntax_error("Missing dictionary value")),
} }
} }
@ -386,8 +408,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
self.skip()?; self.skip()?;
Ok(B::Item::SetValue) Ok(B::Item::SetValue)
} }
_ => _ => Err(self.expected(ExpectedKind::SequenceOrSet)),
Err(self.expected(ExpectedKind::SequenceOrSet)),
} }
} }
@ -443,35 +464,50 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
return Ok(match Tag::try_from(self.peek()?)? { return Ok(match Tag::try_from(self.peek()?)? {
Tag::Embedded => { Tag::Embedded => {
self.skip()?; self.skip()?;
Token::Embedded(self.decode_embedded.decode_embedded( Token::Embedded(
self.source, self.decode_embedded
read_embedded_annotations)?) .decode_embedded(self.source, read_embedded_annotations)?,
)
} }
Tag::False | Tag::False
Tag::True | | Tag::True
Tag::Float | | Tag::Float
Tag::Double | | Tag::Double
Tag::SmallInteger(_) | | Tag::SmallInteger(_)
Tag::MediumInteger(_) | | Tag::MediumInteger(_)
Tag::SignedInteger | | Tag::SignedInteger
Tag::String | | Tag::String
Tag::ByteString | | Tag::ByteString
Tag::Symbol => | Tag::Symbol => Token::Atom(self.demand_next(false)?),
Token::Atom(self.demand_next(false)?),
Tag::Record => { self.skip()?; Token::Compound(CompoundClass::Record) } Tag::Record => {
Tag::Sequence => { self.skip()?; Token::Compound(CompoundClass::Sequence) } self.skip()?;
Tag::Set => { self.skip()?; Token::Compound(CompoundClass::Set) } Token::Compound(CompoundClass::Record)
Tag::Dictionary => { self.skip()?; Token::Compound(CompoundClass::Dictionary) } }
Tag::Sequence => {
self.skip()?;
Token::Compound(CompoundClass::Sequence)
}
Tag::Set => {
self.skip()?;
Token::Compound(CompoundClass::Set)
}
Tag::Dictionary => {
self.skip()?;
Token::Compound(CompoundClass::Dictionary)
}
Tag::End => { self.skip()?; Token::End } Tag::End => {
self.skip()?;
Token::End
}
Tag::Annotation => { Tag::Annotation => {
self.skip()?; self.skip()?;
self.skip_annotations()?; self.skip_annotations()?;
continue continue;
} }
}) });
} }
} }
@ -489,8 +525,14 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
#[inline(always)] #[inline(always)]
fn next_boolean(&mut self) -> ReaderResult<bool> { fn next_boolean(&mut self) -> ReaderResult<bool> {
match self.peek_next_nonannotation_tag()? { match self.peek_next_nonannotation_tag()? {
Tag::False => { self.skip()?; Ok(false) } Tag::False => {
Tag::True => { self.skip()?; Ok(true) } self.skip()?;
Ok(false)
}
Tag::True => {
self.skip()?;
Ok(true)
}
_ => Err(self.expected(ExpectedKind::Boolean)), _ => Err(self.expected(ExpectedKind::Boolean)),
} }
} }
@ -511,21 +553,41 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
let count = self.varint()?; let count = self.varint()?;
Ok(self.read_signed_integer(count)?) Ok(self.read_signed_integer(count)?)
} }
_ => Err(self.expected(ExpectedKind::SignedInteger)) _ => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
fn next_i8(&mut self) -> ReaderResult<i8> { self.next_signed(|n| n.to_i8()) } fn next_i8(&mut self) -> ReaderResult<i8> {
fn next_i16(&mut self) -> ReaderResult<i16> { self.next_signed(|n| n.to_i16()) } self.next_signed(|n| n.to_i8())
fn next_i32(&mut self) -> ReaderResult<i32> { self.next_signed(|n| n.to_i32()) } }
fn next_i64(&mut self) -> ReaderResult<i64> { self.next_signed(|n| n.to_i64()) } fn next_i16(&mut self) -> ReaderResult<i16> {
fn next_i128(&mut self) -> ReaderResult<i128> { self.next_signed(|n| n.to_i128()) } self.next_signed(|n| n.to_i16())
}
fn next_i32(&mut self) -> ReaderResult<i32> {
self.next_signed(|n| n.to_i32())
}
fn next_i64(&mut self) -> ReaderResult<i64> {
self.next_signed(|n| n.to_i64())
}
fn next_i128(&mut self) -> ReaderResult<i128> {
self.next_signed(|n| n.to_i128())
}
fn next_u8(&mut self) -> ReaderResult<u8> { self.next_unsigned(|n| n.to_u8()) } fn next_u8(&mut self) -> ReaderResult<u8> {
fn next_u16(&mut self) -> ReaderResult<u16> { self.next_unsigned(|n| n.to_u16()) } self.next_unsigned(|n| n.to_u8())
fn next_u32(&mut self) -> ReaderResult<u32> { self.next_unsigned(|n| n.to_u32()) } }
fn next_u64(&mut self) -> ReaderResult<u64> { self.next_unsigned(|n| n.to_u64()) } fn next_u16(&mut self) -> ReaderResult<u16> {
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_unsigned(|n| n.to_u128()) } self.next_unsigned(|n| n.to_u16())
}
fn next_u32(&mut self) -> ReaderResult<u32> {
self.next_unsigned(|n| n.to_u32())
}
fn next_u64(&mut self) -> ReaderResult<u64> {
self.next_unsigned(|n| n.to_u64())
}
fn next_u128(&mut self) -> ReaderResult<u128> {
self.next_unsigned(|n| n.to_u128())
}
fn next_f32(&mut self) -> ReaderResult<f32> { fn next_f32(&mut self) -> ReaderResult<f32> {
match self.peek_next_nonannotation_tag()? { match self.peek_next_nonannotation_tag()? {
@ -534,13 +596,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
let mut bs = [0; 4]; let mut bs = [0; 4];
self.readbytes_into(&mut bs)?; self.readbytes_into(&mut bs)?;
Ok(f32::from_bits(u32::from_be_bytes(bs))) Ok(f32::from_bits(u32::from_be_bytes(bs)))
}, }
Tag::Double => { Tag::Double => {
self.skip()?; self.skip()?;
let mut bs = [0; 8]; let mut bs = [0; 8];
self.readbytes_into(&mut bs)?; self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs)) as f32) Ok(f64::from_bits(u64::from_be_bytes(bs)) as f32)
}, }
_ => Err(self.expected(ExpectedKind::Float)), _ => Err(self.expected(ExpectedKind::Float)),
} }
} }
@ -552,19 +614,21 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
let mut bs = [0; 4]; let mut bs = [0; 4];
self.readbytes_into(&mut bs)?; self.readbytes_into(&mut bs)?;
Ok(f32::from_bits(u32::from_be_bytes(bs)) as f64) Ok(f32::from_bits(u32::from_be_bytes(bs)) as f64)
}, }
Tag::Double => { Tag::Double => {
self.skip()?; self.skip()?;
let mut bs = [0; 8]; let mut bs = [0; 8];
self.readbytes_into(&mut bs)?; self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs))) Ok(f64::from_bits(u64::from_be_bytes(bs)))
}, }
_ => Err(self.expected(ExpectedKind::Double)), _ => Err(self.expected(ExpectedKind::Double)),
} }
} }
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> { fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(decodestr(self.next_atomic(Tag::String, ExpectedKind::Symbol)?)?) Ok(decodestr(
self.next_atomic(Tag::String, ExpectedKind::Symbol)?,
)?)
} }
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> { fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
@ -572,16 +636,20 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
} }
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> { fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(decodestr(self.next_atomic(Tag::Symbol, ExpectedKind::Symbol)?)?) Ok(decodestr(
self.next_atomic(Tag::Symbol, ExpectedKind::Symbol)?,
)?)
} }
} }
#[inline(always)] #[inline(always)]
fn decodestr(cow: Cow<'_, [u8]>) -> io::Result<Cow<'_, str>> { fn decodestr(cow: Cow<'_, [u8]>) -> io::Result<Cow<'_, str>> {
match cow { match cow {
Cow::Borrowed(bs) => Cow::Borrowed(bs) => Ok(Cow::Borrowed(
Ok(Cow::Borrowed(std::str::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)), std::str::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?,
Cow::Owned(bs) => )),
Ok(Cow::Owned(String::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)), Cow::Owned(bs) => Ok(Cow::Owned(
String::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?,
)),
} }
} }

View File

@ -1,17 +1,17 @@
use super::super::boundary as B;
use super::super::suspendable::Suspendable;
use super::super::DomainEncode;
use super::super::IOValue;
use super::super::IOValueDomainCodec;
use super::super::NestedValue;
use super::constants::Tag;
use num::bigint::BigInt; use num::bigint::BigInt;
use num::cast::ToPrimitive; use num::cast::ToPrimitive;
use std::convert::TryInto; use std::convert::TryInto;
use std::io; use std::io;
use std::ops::DerefMut; use std::ops::DerefMut;
use super::constants::Tag;
use super::super::DomainEncode;
use super::super::IOValue;
use super::super::IOValueDomainCodec;
use super::super::NestedValue;
use super::super::boundary as B;
use super::super::suspendable::Suspendable;
use super::super::writer::{Writer, CompoundWriter, varint}; use super::super::writer::{varint, CompoundWriter, Writer};
pub struct PackedWriter<W: io::Write>(Suspendable<W>); pub struct PackedWriter<W: io::Write>(Suspendable<W>);
@ -51,7 +51,9 @@ impl<W: io::Write> PackedWriter<W> {
#[inline(always)] #[inline(always)]
pub fn write_medium_integer(&mut self, bs: &[u8]) -> io::Result<()> { pub fn write_medium_integer(&mut self, bs: &[u8]) -> io::Result<()> {
let count: u8 = bs.len().try_into().unwrap(); let count: u8 = bs.len().try_into().unwrap();
if !(1..=16).contains(&count) { panic!("Invalid medium_integer count: {}", count) } if !(1..=16).contains(&count) {
panic!("Invalid medium_integer count: {}", count)
}
self.write_byte(Tag::MediumInteger(count).into())?; self.write_byte(Tag::MediumInteger(count).into())?;
self.w().write_all(bs) self.w().write_all(bs)
} }
@ -109,7 +111,9 @@ impl BinaryOrderWriter {
#[inline(always)] #[inline(always)]
fn finish<W: WriteWriter>(mut self, w: &mut W) -> io::Result<()> { fn finish<W: WriteWriter>(mut self, w: &mut W) -> io::Result<()> {
if !self.buffer().is_empty() { panic!("Missing final boundary()"); } if !self.buffer().is_empty() {
panic!("Missing final boundary()");
}
self.items_mut().pop(); self.items_mut().pop();
self.items_mut().sort(); self.items_mut().sort();
for bs in self.items() { for bs in self.items() {
@ -158,13 +162,11 @@ impl CompoundWriter for BinaryOrderWriter {
#[inline(always)] #[inline(always)]
fn boundary(&mut self, b: &B::Type) -> io::Result<()> { fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
match b.closing { match b.closing {
Some(B::Item::DictionaryValue) | Some(B::Item::DictionaryValue)
Some(B::Item::RecordField) | | Some(B::Item::RecordField)
Some(B::Item::SequenceValue) | | Some(B::Item::SequenceValue)
Some(B::Item::SetValue) => | Some(B::Item::SetValue) => self.items_mut().push(vec![]),
self.items_mut().push(vec![]), _ => (),
_ =>
()
} }
Ok(()) Ok(())
} }
@ -276,14 +278,13 @@ impl Writer for BinaryOrderWriter {
} }
macro_rules! fits_in_bytes { macro_rules! fits_in_bytes {
($v:ident, $limit:literal) => ({ ($v:ident, $limit:literal) => {{
let bits = $limit * 8 - 1; let bits = $limit * 8 - 1;
$v >= -(2 << bits) && $v < (2 << bits) $v >= -(2 << bits) && $v < (2 << bits)
}) }};
} }
impl<W: io::Write> Writer for PackedWriter<W> impl<W: io::Write> Writer for PackedWriter<W> {
{
type AnnWriter = Self; type AnnWriter = Self;
type RecWriter = Self; type RecWriter = Self;
type SeqWriter = Self; type SeqWriter = Self;
@ -321,120 +322,166 @@ impl<W: io::Write> Writer for PackedWriter<W>
#[inline(always)] #[inline(always)]
fn write_i8(&mut self, v: i8) -> io::Result<()> { fn write_i8(&mut self, v: i8) -> io::Result<()> {
if v >= -3 && v <= 12 { return self.write_tag(Tag::SmallInteger(v)) } if v >= -3 && v <= 12 {
return self.write_tag(Tag::SmallInteger(v));
}
self.write_medium_integer(&[v as u8]) self.write_medium_integer(&[v as u8])
} }
#[inline(always)] #[inline(always)]
fn write_u8(&mut self, v: u8) -> io::Result<()> { fn write_u8(&mut self, v: u8) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i8(w) } if let Ok(w) = v.try_into() {
return self.write_i8(w);
}
self.write_medium_integer(&[0, v]) self.write_medium_integer(&[0, v])
} }
#[inline(always)] #[inline(always)]
fn write_i16(&mut self, v: i16) -> io::Result<()> { fn write_i16(&mut self, v: i16) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i8(w) } if let Ok(w) = v.try_into() {
return self.write_i8(w);
}
self.write_medium_integer(&[(v >> 8) as u8, (v & 255) as u8]) self.write_medium_integer(&[(v >> 8) as u8, (v & 255) as u8])
} }
#[inline(always)] #[inline(always)]
fn write_u16(&mut self, v: u16) -> io::Result<()> { fn write_u16(&mut self, v: u16) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) } if let Ok(w) = v.try_into() {
return self.write_i16(w);
}
self.write_medium_integer(&[0, (v >> 8) as u8, (v & 255) as u8]) self.write_medium_integer(&[0, (v >> 8) as u8, (v & 255) as u8])
} }
#[inline(always)] #[inline(always)]
fn write_i32(&mut self, v: i32) -> io::Result<()> { fn write_i32(&mut self, v: i32) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) } if let Ok(w) = v.try_into() {
if fits_in_bytes!(v, 3) { return self.write_i16(w);
return self.write_medium_integer(&[(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
} }
self.write_medium_integer(&[(v >> 24) as u8, if fits_in_bytes!(v, 3) {
(v >> 16) as u8, return self.write_medium_integer(&[(v >> 16) as u8, (v >> 8) as u8, (v & 255) as u8]);
(v >> 8) as u8, }
(v & 255) as u8]) self.write_medium_integer(&[
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8,
])
} }
#[inline(always)] #[inline(always)]
fn write_u32(&mut self, v: u32) -> io::Result<()> { fn write_u32(&mut self, v: u32) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) } if let Ok(w) = v.try_into() {
self.write_medium_integer(&[0, return self.write_i32(w);
(v >> 24) as u8, }
(v >> 16) as u8, self.write_medium_integer(&[
(v >> 8) as u8, 0,
(v & 255) as u8]) (v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8,
])
} }
#[inline(always)] #[inline(always)]
fn write_i64(&mut self, v: i64) -> io::Result<()> { fn write_i64(&mut self, v: i64) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) } if let Ok(w) = v.try_into() {
return self.write_i32(w);
}
if fits_in_bytes!(v, 5) { if fits_in_bytes!(v, 5) {
return self.write_medium_integer(&[(v >> 32) as u8, return self.write_medium_integer(&[
(v >> 24) as u8, (v >> 32) as u8,
(v >> 16) as u8, (v >> 24) as u8,
(v >> 8) as u8, (v >> 16) as u8,
(v & 255) as u8]); (v >> 8) as u8,
(v & 255) as u8,
]);
} }
if fits_in_bytes!(v, 6) { if fits_in_bytes!(v, 6) {
return self.write_medium_integer(&[(v >> 40) as u8, return self.write_medium_integer(&[
(v >> 32) as u8, (v >> 40) as u8,
(v >> 24) as u8, (v >> 32) as u8,
(v >> 16) as u8, (v >> 24) as u8,
(v >> 8) as u8, (v >> 16) as u8,
(v & 255) as u8]); (v >> 8) as u8,
(v & 255) as u8,
]);
} }
if fits_in_bytes!(v, 7) { if fits_in_bytes!(v, 7) {
return self.write_medium_integer(&[(v >> 48) as u8, return self.write_medium_integer(&[
(v >> 40) as u8, (v >> 48) as u8,
(v >> 32) as u8, (v >> 40) as u8,
(v >> 24) as u8, (v >> 32) as u8,
(v >> 16) as u8, (v >> 24) as u8,
(v >> 8) as u8, (v >> 16) as u8,
(v & 255) as u8]); (v >> 8) as u8,
(v & 255) as u8,
]);
} }
self.write_medium_integer(&[(v >> 56) as u8, self.write_medium_integer(&[
(v >> 48) as u8, (v >> 56) as u8,
(v >> 40) as u8, (v >> 48) as u8,
(v >> 32) as u8, (v >> 40) as u8,
(v >> 24) as u8, (v >> 32) as u8,
(v >> 16) as u8, (v >> 24) as u8,
(v >> 8) as u8, (v >> 16) as u8,
(v & 255) as u8]) (v >> 8) as u8,
(v & 255) as u8,
])
} }
#[inline(always)] #[inline(always)]
fn write_u64(&mut self, v: u64) -> io::Result<()> { fn write_u64(&mut self, v: u64) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) } if let Ok(w) = v.try_into() {
self.write_medium_integer(&[0, return self.write_i64(w);
(v >> 56) as u8, }
(v >> 48) as u8, self.write_medium_integer(&[
(v >> 40) as u8, 0,
(v >> 32) as u8, (v >> 56) as u8,
(v >> 24) as u8, (v >> 48) as u8,
(v >> 16) as u8, (v >> 40) as u8,
(v >> 8) as u8, (v >> 32) as u8,
(v & 255) as u8]) (v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8,
])
} }
#[inline(always)] #[inline(always)]
fn write_i128(&mut self, v: i128) -> io::Result<()> { fn write_i128(&mut self, v: i128) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) } if let Ok(w) = v.try_into() {
return self.write_i64(w);
}
let bs: [u8; 16] = v.to_be_bytes(); let bs: [u8; 16] = v.to_be_bytes();
if fits_in_bytes!(v, 9) { return self.write_medium_integer(&bs[7..]); } if fits_in_bytes!(v, 9) {
if fits_in_bytes!(v, 10) { return self.write_medium_integer(&bs[6..]); } return self.write_medium_integer(&bs[7..]);
if fits_in_bytes!(v, 11) { return self.write_medium_integer(&bs[5..]); } }
if fits_in_bytes!(v, 12) { return self.write_medium_integer(&bs[4..]); } if fits_in_bytes!(v, 10) {
if fits_in_bytes!(v, 13) { return self.write_medium_integer(&bs[3..]); } return self.write_medium_integer(&bs[6..]);
if fits_in_bytes!(v, 14) { return self.write_medium_integer(&bs[2..]); } }
if fits_in_bytes!(v, 15) { return self.write_medium_integer(&bs[1..]); } if fits_in_bytes!(v, 11) {
return self.write_medium_integer(&bs[5..]);
}
if fits_in_bytes!(v, 12) {
return self.write_medium_integer(&bs[4..]);
}
if fits_in_bytes!(v, 13) {
return self.write_medium_integer(&bs[3..]);
}
if fits_in_bytes!(v, 14) {
return self.write_medium_integer(&bs[2..]);
}
if fits_in_bytes!(v, 15) {
return self.write_medium_integer(&bs[1..]);
}
self.write_medium_integer(&bs) self.write_medium_integer(&bs)
} }
#[inline(always)] #[inline(always)]
fn write_u128(&mut self, v: u128) -> io::Result<()> { fn write_u128(&mut self, v: u128) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i128(w) } if let Ok(w) = v.try_into() {
return self.write_i128(w);
}
let bs: [u8; 16] = v.to_be_bytes(); let bs: [u8; 16] = v.to_be_bytes();
self.write_tag(Tag::SignedInteger)?; self.write_tag(Tag::SignedInteger)?;
varint(&mut self.w(), 17)?; varint(&mut self.w(), 17)?;
@ -446,12 +493,10 @@ impl<W: io::Write> Writer for PackedWriter<W>
fn write_int(&mut self, v: &BigInt) -> io::Result<()> { fn write_int(&mut self, v: &BigInt) -> io::Result<()> {
match v.to_i8() { match v.to_i8() {
Some(n) => self.write_i8(n), Some(n) => self.write_i8(n),
None => { None => match v.to_i128() {
match v.to_i128() { Some(n) => self.write_i128(n),
Some(n) => self.write_i128(n), None => self.write_atom(Tag::SignedInteger, &v.to_signed_bytes_be()),
None => self.write_atom(Tag::SignedInteger, &v.to_signed_bytes_be()), },
}
}
} }
} }

View File

@ -1,9 +1,11 @@
use crate::error::{self, ExpectedKind, Received, io_eof}; use crate::error::{self, io_eof, ExpectedKind, Received};
use std::borrow::Cow; use std::borrow::Cow;
use std::io; use std::io;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::boundary as B;
use super::signed_integer::SignedInteger;
use super::CompoundClass; use super::CompoundClass;
use super::DomainDecode; use super::DomainDecode;
use super::DomainParse; use super::DomainParse;
@ -13,8 +15,6 @@ use super::IOValue;
use super::IOValueDomainCodec; use super::IOValueDomainCodec;
use super::NestedValue; use super::NestedValue;
use super::ViaCodec; use super::ViaCodec;
use super::boundary as B;
use super::signed_integer::SignedInteger;
pub type ReaderResult<T> = std::result::Result<T, error::Error>; pub type ReaderResult<T> = std::result::Result<T, error::Error>;
@ -72,37 +72,72 @@ pub trait Reader<'de, N: NestedValue> {
} }
fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> { fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> {
Ok(self.demand_next(false)?.value().to_signedinteger()?.to_owned()) Ok(self
.demand_next(false)?
.value()
.to_signedinteger()?
.to_owned())
} }
fn next_i8(&mut self) -> ReaderResult<i8> { self.demand_next(false)?.value().to_i8() } fn next_i8(&mut self) -> ReaderResult<i8> {
fn next_u8(&mut self) -> ReaderResult<u8> { self.demand_next(false)?.value().to_u8() } self.demand_next(false)?.value().to_i8()
fn next_i16(&mut self) -> ReaderResult<i16> { self.demand_next(false)?.value().to_i16() } }
fn next_u16(&mut self) -> ReaderResult<u16> { self.demand_next(false)?.value().to_u16() } fn next_u8(&mut self) -> ReaderResult<u8> {
fn next_i32(&mut self) -> ReaderResult<i32> { self.demand_next(false)?.value().to_i32() } self.demand_next(false)?.value().to_u8()
fn next_u32(&mut self) -> ReaderResult<u32> { self.demand_next(false)?.value().to_u32() } }
fn next_i64(&mut self) -> ReaderResult<i64> { self.demand_next(false)?.value().to_i64() } fn next_i16(&mut self) -> ReaderResult<i16> {
fn next_u64(&mut self) -> ReaderResult<u64> { self.demand_next(false)?.value().to_u64() } self.demand_next(false)?.value().to_i16()
fn next_i128(&mut self) -> ReaderResult<i128> { self.demand_next(false)?.value().to_i128() } }
fn next_u128(&mut self) -> ReaderResult<u128> { self.demand_next(false)?.value().to_u128() } fn next_u16(&mut self) -> ReaderResult<u16> {
fn next_f32(&mut self) -> ReaderResult<f32> { self.demand_next(false)?.value().to_f32() } self.demand_next(false)?.value().to_u16()
fn next_f64(&mut self) -> ReaderResult<f64> { self.demand_next(false)?.value().to_f64() } }
fn next_char(&mut self) -> ReaderResult<char> { self.demand_next(false)?.value().to_char() } fn next_i32(&mut self) -> ReaderResult<i32> {
self.demand_next(false)?.value().to_i32()
}
fn next_u32(&mut self) -> ReaderResult<u32> {
self.demand_next(false)?.value().to_u32()
}
fn next_i64(&mut self) -> ReaderResult<i64> {
self.demand_next(false)?.value().to_i64()
}
fn next_u64(&mut self) -> ReaderResult<u64> {
self.demand_next(false)?.value().to_u64()
}
fn next_i128(&mut self) -> ReaderResult<i128> {
self.demand_next(false)?.value().to_i128()
}
fn next_u128(&mut self) -> ReaderResult<u128> {
self.demand_next(false)?.value().to_u128()
}
fn next_f32(&mut self) -> ReaderResult<f32> {
self.demand_next(false)?.value().to_f32()
}
fn next_f64(&mut self) -> ReaderResult<f64> {
self.demand_next(false)?.value().to_f64()
}
fn next_char(&mut self) -> ReaderResult<char> {
self.demand_next(false)?.value().to_char()
}
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> { fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_string()?.to_owned())) Ok(Cow::Owned(
self.demand_next(false)?.value().to_string()?.to_owned(),
))
} }
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> { fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_bytestring()?.to_owned())) Ok(Cow::Owned(
self.demand_next(false)?.value().to_bytestring()?.to_owned(),
))
} }
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> { fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_symbol()?.to_owned())) Ok(Cow::Owned(
self.demand_next(false)?.value().to_symbol()?.to_owned(),
))
} }
fn open_option(&mut self) -> ReaderResult<Option<B::Type>> fn open_option(&mut self) -> ReaderResult<Option<B::Type>> {
{
let b = self.open_record(None)?; let b = self.open_record(None)?;
let label: &str = &self.next_symbol()?; let label: &str = &self.next_symbol()?;
match label { match label {
@ -110,29 +145,30 @@ pub trait Reader<'de, N: NestedValue> {
self.ensure_complete(b, &B::Item::RecordField)?; self.ensure_complete(b, &B::Item::RecordField)?;
Ok(None) Ok(None)
} }
"Some" => "Some" => Ok(Some(b)),
Ok(Some(b)), _ => Err(error::Error::Expected(
_ => ExpectedKind::Option,
Err(error::Error::Expected(ExpectedKind::Option, Received::ReceivedRecordWithLabel(label.to_owned()),
Received::ReceivedRecordWithLabel(label.to_owned()))), )),
} }
} }
fn open_simple_record(&mut self, name: &str, arity: Option<usize>) -> ReaderResult<B::Type> fn open_simple_record(&mut self, name: &str, arity: Option<usize>) -> ReaderResult<B::Type> {
{
let b = self.open_record(arity)?; let b = self.open_record(arity)?;
let label: &str = &self.next_symbol()?; let label: &str = &self.next_symbol()?;
if label == name { if label == name {
Ok(b) Ok(b)
} else { } else {
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity), Err(error::Error::Expected(
Received::ReceivedRecordWithLabel(label.to_owned()))) ExpectedKind::SimpleRecord(name.to_owned(), arity),
Received::ReceivedRecordWithLabel(label.to_owned()),
))
} }
} }
fn configured(self, read_annotations: bool) -> ConfiguredReader<'de, N, Self> fn configured(self, read_annotations: bool) -> ConfiguredReader<'de, N, Self>
where where
Self: std::marker::Sized Self: std::marker::Sized,
{ {
ConfiguredReader { ConfiguredReader {
reader: self, reader: self,
@ -218,7 +254,6 @@ impl<'r, 'de, N: NestedValue, R: Reader<'de, N>> Reader<'de, N> for &'r mut R {
} }
} }
pub trait BinarySource<'de>: Sized { pub trait BinarySource<'de>: Sized {
type Mark; type Mark;
fn mark(&mut self) -> io::Result<Self::Mark>; fn mark(&mut self) -> io::Result<Self::Mark>;
@ -236,9 +271,9 @@ pub trait BinarySource<'de>: Sized {
super::PackedReader::new(self, decode_embedded) super::PackedReader::new(self, decode_embedded)
} }
fn packed_iovalues(&mut self) -> fn packed_iovalues(
super::PackedReader<'de, '_, IOValue, IOValueDomainCodec, Self> &mut self,
{ ) -> super::PackedReader<'de, '_, IOValue, IOValueDomainCodec, Self> {
self.packed(IOValueDomainCodec) self.packed(IOValueDomainCodec)
} }
@ -249,9 +284,9 @@ pub trait BinarySource<'de>: Sized {
super::TextReader::new(self, decode_embedded) super::TextReader::new(self, decode_embedded)
} }
fn text_iovalues(&mut self) -> fn text_iovalues(
super::TextReader<'de, '_, IOValue, ViaCodec<IOValueDomainCodec>, Self> &mut self,
{ ) -> super::TextReader<'de, '_, IOValue, ViaCodec<IOValueDomainCodec>, Self> {
self.text::<IOValue, _>(ViaCodec::new(IOValueDomainCodec)) self.text::<IOValue, _>(ViaCodec::new(IOValueDomainCodec))
} }
} }
@ -285,7 +320,9 @@ impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
#[inline(always)] #[inline(always)]
fn skip(&mut self) -> io::Result<()> { fn skip(&mut self) -> io::Result<()> {
if self.buf.is_none() { unreachable!(); } if self.buf.is_none() {
unreachable!();
}
self.buf = None; self.buf = None;
Ok(()) Ok(())
} }
@ -310,7 +347,9 @@ impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
#[inline(always)] #[inline(always)]
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> { fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
if self.buf.is_some() { unreachable!(); } if self.buf.is_some() {
unreachable!();
}
let mut bs = vec![0; count]; let mut bs = vec![0; count];
self.read.read_exact(&mut bs)?; self.read.read_exact(&mut bs)?;
Ok(Cow::Owned(bs)) Ok(Cow::Owned(bs))
@ -318,7 +357,9 @@ impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
#[inline(always)] #[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> { fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
if self.buf.is_some() { unreachable!(); } if self.buf.is_some() {
unreachable!();
}
self.read.read_exact(bs) self.read.read_exact(bs)
} }
} }
@ -351,7 +392,9 @@ impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
#[inline(always)] #[inline(always)]
fn skip(&mut self) -> io::Result<()> { fn skip(&mut self) -> io::Result<()> {
if self.index >= self.bytes.len() { unreachable!(); } if self.index >= self.bytes.len() {
unreachable!();
}
self.index += 1; self.index += 1;
Ok(()) Ok(())
} }
@ -370,7 +413,7 @@ impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
if self.index + count > self.bytes.len() { if self.index + count > self.bytes.len() {
Err(io_eof()) Err(io_eof())
} else { } else {
let bs = &self.bytes[self.index..self.index+count]; let bs = &self.bytes[self.index..self.index + count];
self.index += count; self.index += count;
Ok(Cow::Borrowed(bs)) Ok(Cow::Borrowed(bs))
} }
@ -382,7 +425,7 @@ impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
if self.index + count > self.bytes.len() { if self.index + count > self.bytes.len() {
Err(io_eof()) Err(io_eof())
} else { } else {
bs.copy_from_slice(&self.bytes[self.index..self.index+count]); bs.copy_from_slice(&self.bytes[self.index..self.index + count]);
self.index += count; self.index += count;
Ok(()) Ok(())
} }

View File

@ -14,16 +14,16 @@ use std::string::String;
use std::sync::Arc; use std::sync::Arc;
use std::vec::Vec; use std::vec::Vec;
pub use std::collections::BTreeSet as Set;
pub use std::collections::BTreeMap as Map; pub use std::collections::BTreeMap as Map;
pub use std::collections::BTreeSet as Set;
use super::signed_integer::SignedInteger;
use super::text;
use super::DebugDomainEncode; use super::DebugDomainEncode;
use super::FromStrDomainParse; use super::FromStrDomainParse;
use super::IOValueDomainCodec; use super::IOValueDomainCodec;
use super::TextWriter; use super::TextWriter;
use super::Writer; use super::Writer;
use super::signed_integer::SignedInteger;
use super::text;
use crate::error::{Error, ExpectedKind, Received}; use crate::error::{Error, ExpectedKind, Received};
pub trait Domain: Sized + Debug + Eq + Hash + Ord { pub trait Domain: Sized + Debug + Eq + Hash + Ord {
@ -45,12 +45,18 @@ pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord {
type Embedded: Embeddable; type Embedded: Embeddable;
#[inline(always)] #[inline(always)]
fn new<V>(v: V) -> Self where Value<Self>: From<V> { fn new<V>(v: V) -> Self
where
Value<Self>: From<V>,
{
Value::from(v).wrap() Value::from(v).wrap()
} }
#[inline(always)] #[inline(always)]
fn domain<E>(e: E) -> Self where Self::Embedded: From<E> { fn domain<E>(e: E) -> Self
where
Self::Embedded: From<E>,
{
Value::Embedded(e.into()).wrap() Value::Embedded(e.into()).wrap()
} }
@ -89,18 +95,25 @@ pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord {
fn copy_via<M: NestedValue, F, Err>(&self, f: &mut F) -> Result<M, Err> fn copy_via<M: NestedValue, F, Err>(&self, f: &mut F) -> Result<M, Err>
where where
F: FnMut(&Self::Embedded) -> Result<Value<M>, Err> F: FnMut(&Self::Embedded) -> Result<Value<M>, Err>,
{ {
Ok(M::wrap(self.annotations().copy_via(f)?, self.value().copy_via(f)?)) Ok(M::wrap(
self.annotations().copy_via(f)?,
self.value().copy_via(f)?,
))
} }
fn foreach_embedded<F, Err>(&self, f: &mut F) -> Result<(), Err> fn foreach_embedded<F, Err>(&self, f: &mut F) -> Result<(), Err>
where where
F: FnMut(&Self::Embedded) -> Result<(), Err> F: FnMut(&Self::Embedded) -> Result<(), Err>,
{ {
match &self.annotations().0 { match &self.annotations().0 {
None => (), None => (),
Some(vs) => for v in vs.iter() { v.foreach_embedded(f)? }, Some(vs) => {
for v in vs.iter() {
v.foreach_embedded(f)?
}
}
} }
self.value().foreach_embedded(f) self.value().foreach_embedded(f)
} }
@ -201,7 +214,10 @@ impl<N> Record<N> {
} }
#[inline(always)] #[inline(always)]
pub fn finish(self) -> Value<N> where N: NestedValue { pub fn finish(self) -> Value<N>
where
N: NestedValue,
{
Value::Record(self) Value::Record(self)
} }
} }
@ -234,8 +250,12 @@ impl Ord for Float {
fn cmp(&self, other: &Self) -> Ordering { fn cmp(&self, other: &Self) -> Ordering {
let mut a: u32 = self.0.to_bits(); let mut a: u32 = self.0.to_bits();
let mut b: u32 = other.0.to_bits(); let mut b: u32 = other.0.to_bits();
if a & 0x8000_0000 != 0 { a ^= 0x7fff_ffff; } if a & 0x8000_0000 != 0 {
if b & 0x8000_0000 != 0 { b ^= 0x7fff_ffff; } a ^= 0x7fff_ffff;
}
if b & 0x8000_0000 != 0 {
b ^= 0x7fff_ffff;
}
(a as i32).cmp(&(b as i32)) (a as i32).cmp(&(b as i32))
} }
} }
@ -276,8 +296,12 @@ impl Ord for Double {
fn cmp(&self, other: &Self) -> Ordering { fn cmp(&self, other: &Self) -> Ordering {
let mut a: u64 = self.0.to_bits(); let mut a: u64 = self.0.to_bits();
let mut b: u64 = other.0.to_bits(); let mut b: u64 = other.0.to_bits();
if a & 0x8000_0000_0000_0000 != 0 { a ^= 0x7fff_ffff_ffff_ffff; } if a & 0x8000_0000_0000_0000 != 0 {
if b & 0x8000_0000_0000_0000 != 0 { b ^= 0x7fff_ffff_ffff_ffff; } a ^= 0x7fff_ffff_ffff_ffff;
}
if b & 0x8000_0000_0000_0000 != 0 {
b ^= 0x7fff_ffff_ffff_ffff;
}
(a as i64).cmp(&(b as i64)) (a as i64).cmp(&(b as i64))
} }
} }
@ -290,42 +314,162 @@ impl PartialOrd for Double {
impl Eq for Double {} impl Eq for Double {}
impl<N: NestedValue> From<bool> for Value<N> { fn from(v: bool) -> Self { Value::Boolean(v) } } impl<N: NestedValue> From<bool> for Value<N> {
impl<N: NestedValue> From<&bool> for Value<N> { fn from(v: &bool) -> Self { Value::Boolean(*v) } } fn from(v: bool) -> Self {
Value::Boolean(v)
}
}
impl<N: NestedValue> From<&bool> for Value<N> {
fn from(v: &bool) -> Self {
Value::Boolean(*v)
}
}
impl<N: NestedValue> From<f32> for Value<N> { fn from(v: f32) -> Self { Value::Float(Float::from(v)) } } impl<N: NestedValue> From<f32> for Value<N> {
impl<N: NestedValue> From<&f32> for Value<N> { fn from(v: &f32) -> Self { Value::Float(Float::from(*v)) } } fn from(v: f32) -> Self {
impl<N: NestedValue> From<&Float> for Value<N> { fn from(v: &Float) -> Self { Value::Float(v.clone()) } } Value::Float(Float::from(v))
impl<N: NestedValue> From<f64> for Value<N> { fn from(v: f64) -> Self { Value::Double(Double::from(v)) } } }
impl<N: NestedValue> From<&f64> for Value<N> { fn from(v: &f64) -> Self { Value::Double(Double::from(*v)) } } }
impl<N: NestedValue> From<&Double> for Value<N> { fn from(v: &Double) -> Self { Value::Double(v.clone()) } } impl<N: NestedValue> From<&f32> for Value<N> {
fn from(v: &f32) -> Self {
Value::Float(Float::from(*v))
}
}
impl<N: NestedValue> From<&Float> for Value<N> {
fn from(v: &Float) -> Self {
Value::Float(v.clone())
}
}
impl<N: NestedValue> From<f64> for Value<N> {
fn from(v: f64) -> Self {
Value::Double(Double::from(v))
}
}
impl<N: NestedValue> From<&f64> for Value<N> {
fn from(v: &f64) -> Self {
Value::Double(Double::from(*v))
}
}
impl<N: NestedValue> From<&Double> for Value<N> {
fn from(v: &Double) -> Self {
Value::Double(v.clone())
}
}
impl<N: NestedValue> From<u8> for Value<N> { fn from(v: u8) -> Self { Value::from(i128::from(v)) } } impl<N: NestedValue> From<u8> for Value<N> {
impl<N: NestedValue> From<i8> for Value<N> { fn from(v: i8) -> Self { Value::from(i128::from(v)) } } fn from(v: u8) -> Self {
impl<N: NestedValue> From<u16> for Value<N> { fn from(v: u16) -> Self { Value::from(i128::from(v)) } } Value::from(i128::from(v))
impl<N: NestedValue> From<i16> for Value<N> { fn from(v: i16) -> Self { Value::from(i128::from(v)) } } }
impl<N: NestedValue> From<u32> for Value<N> { fn from(v: u32) -> Self { Value::from(i128::from(v)) } } }
impl<N: NestedValue> From<i32> for Value<N> { fn from(v: i32) -> Self { Value::from(i128::from(v)) } } impl<N: NestedValue> From<i8> for Value<N> {
impl<N: NestedValue> From<u64> for Value<N> { fn from(v: u64) -> Self { Value::from(i128::from(v)) } } fn from(v: i8) -> Self {
impl<N: NestedValue> From<i64> for Value<N> { fn from(v: i64) -> Self { Value::from(i128::from(v)) } } Value::from(i128::from(v))
impl<N: NestedValue> From<usize> for Value<N> { fn from(v: usize) -> Self { Value::from(v as u128) } } }
impl<N: NestedValue> From<isize> for Value<N> { fn from(v: isize) -> Self { Value::from(v as i128) } } }
impl<N: NestedValue> From<u128> for Value<N> { fn from(v: u128) -> Self { Value::SignedInteger(SignedInteger::from(v)) } } impl<N: NestedValue> From<u16> for Value<N> {
impl<N: NestedValue> From<i128> for Value<N> { fn from(v: i128) -> Self { Value::SignedInteger(SignedInteger::from(v)) } } fn from(v: u16) -> Self {
impl<N: NestedValue> From<&BigInt> for Value<N> { fn from(v: &BigInt) -> Self { Value::SignedInteger(SignedInteger::from(Cow::Borrowed(v))) } } Value::from(i128::from(v))
impl<N: NestedValue> From<BigInt> for Value<N> { fn from(v: BigInt) -> Self { Value::SignedInteger(SignedInteger::from(Cow::Owned(v))) } } }
impl<N: NestedValue> From<&SignedInteger> for Value<N> { fn from(v: &SignedInteger) -> Self { Value::SignedInteger(v.clone()) } } }
impl<N: NestedValue> From<i16> for Value<N> {
fn from(v: i16) -> Self {
Value::from(i128::from(v))
}
}
impl<N: NestedValue> From<u32> for Value<N> {
fn from(v: u32) -> Self {
Value::from(i128::from(v))
}
}
impl<N: NestedValue> From<i32> for Value<N> {
fn from(v: i32) -> Self {
Value::from(i128::from(v))
}
}
impl<N: NestedValue> From<u64> for Value<N> {
fn from(v: u64) -> Self {
Value::from(i128::from(v))
}
}
impl<N: NestedValue> From<i64> for Value<N> {
fn from(v: i64) -> Self {
Value::from(i128::from(v))
}
}
impl<N: NestedValue> From<usize> for Value<N> {
fn from(v: usize) -> Self {
Value::from(v as u128)
}
}
impl<N: NestedValue> From<isize> for Value<N> {
fn from(v: isize) -> Self {
Value::from(v as i128)
}
}
impl<N: NestedValue> From<u128> for Value<N> {
fn from(v: u128) -> Self {
Value::SignedInteger(SignedInteger::from(v))
}
}
impl<N: NestedValue> From<i128> for Value<N> {
fn from(v: i128) -> Self {
Value::SignedInteger(SignedInteger::from(v))
}
}
impl<N: NestedValue> From<&BigInt> for Value<N> {
fn from(v: &BigInt) -> Self {
Value::SignedInteger(SignedInteger::from(Cow::Borrowed(v)))
}
}
impl<N: NestedValue> From<BigInt> for Value<N> {
fn from(v: BigInt) -> Self {
Value::SignedInteger(SignedInteger::from(Cow::Owned(v)))
}
}
impl<N: NestedValue> From<&SignedInteger> for Value<N> {
fn from(v: &SignedInteger) -> Self {
Value::SignedInteger(v.clone())
}
}
impl<N: NestedValue> From<&str> for Value<N> { fn from(v: &str) -> Self { Value::String(String::from(v)) } } impl<N: NestedValue> From<&str> for Value<N> {
impl<N: NestedValue> From<String> for Value<N> { fn from(v: String) -> Self { Value::String(v) } } fn from(v: &str) -> Self {
impl<N: NestedValue> From<&String> for Value<N> { fn from(v: &String) -> Self { Value::String(v.to_owned()) } } Value::String(String::from(v))
}
}
impl<N: NestedValue> From<String> for Value<N> {
fn from(v: String) -> Self {
Value::String(v)
}
}
impl<N: NestedValue> From<&String> for Value<N> {
fn from(v: &String) -> Self {
Value::String(v.to_owned())
}
}
impl<N: NestedValue> From<&[u8]> for Value<N> { fn from(v: &[u8]) -> Self { Value::ByteString(Vec::from(v)) } } impl<N: NestedValue> From<&[u8]> for Value<N> {
fn from(v: &[u8]) -> Self {
Value::ByteString(Vec::from(v))
}
}
// impl<N: NestedValue> From<Vec<u8>> for Value<N> { fn from(v: Vec<u8>) -> Self { Value::ByteString(v) } } // impl<N: NestedValue> From<Vec<u8>> for Value<N> { fn from(v: Vec<u8>) -> Self { Value::ByteString(v) } }
impl<N: NestedValue> From<Vec<N>> for Value<N> { fn from(v: Vec<N>) -> Self { Value::Sequence(v) } } impl<N: NestedValue> From<Vec<N>> for Value<N> {
impl<N: NestedValue> From<Set<N>> for Value<N> { fn from(v: Set<N>) -> Self { Value::Set(v) } } fn from(v: Vec<N>) -> Self {
impl<N: NestedValue> From<Map<N, N>> for Value<N> { fn from(v: Map<N, N>) -> Self { Value::Dictionary(v) } } Value::Sequence(v)
}
}
impl<N: NestedValue> From<Set<N>> for Value<N> {
fn from(v: Set<N>) -> Self {
Value::Set(v)
}
}
impl<N: NestedValue> From<Map<N, N>> for Value<N> {
fn from(v: Map<N, N>) -> Self {
Value::Dictionary(v)
}
}
impl<N: NestedValue> Debug for Value<N> { impl<N: NestedValue> Debug for Value<N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@ -333,8 +477,11 @@ impl<N: NestedValue> Debug for Value<N> {
} }
} }
impl<Err: Into<io::Error>, D: Embeddable + std::str::FromStr<Err = Err>, N: NestedValue<Embedded = D>> impl<
std::str::FromStr for Value<N> Err: Into<io::Error>,
D: Embeddable + std::str::FromStr<Err = Err>,
N: NestedValue<Embedded = D>,
> std::str::FromStr for Value<N>
{ {
type Err = io::Error; type Err = io::Error;
@ -369,14 +516,14 @@ impl<N: NestedValue> Value<N> {
pub fn children(&self) -> Vec<N> { pub fn children(&self) -> Vec<N> {
match self { match self {
Value::Boolean(_) | Value::Boolean(_)
Value::Float(_) | | Value::Float(_)
Value::Double(_) | | Value::Double(_)
Value::SignedInteger(_) | | Value::SignedInteger(_)
Value::String(_) | | Value::String(_)
Value::ByteString(_) | | Value::ByteString(_)
Value::Symbol(_) | | Value::Symbol(_)
Value::Embedded(_) => vec![], | Value::Embedded(_) => vec![],
Value::Record(r) => r.fields().to_vec(), Value::Record(r) => r.fields().to_vec(),
Value::Sequence(vs) => vs.clone(), Value::Sequence(vs) => vs.clone(),
@ -386,7 +533,10 @@ impl<N: NestedValue> Value<N> {
} }
fn expected(&self, k: ExpectedKind) -> Error { fn expected(&self, k: ExpectedKind) -> Error {
Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", self.clone().wrap()))) Error::Expected(
k,
Received::ReceivedOtherValue(format!("{:?}", self.clone().wrap())),
)
} }
#[inline(always)] #[inline(always)]
@ -414,7 +564,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_boolean(&self) -> Result<bool, Error> { pub fn to_boolean(&self) -> Result<bool, Error> {
self.as_boolean().ok_or_else(|| self.expected(ExpectedKind::Boolean)) self.as_boolean()
.ok_or_else(|| self.expected(ExpectedKind::Boolean))
} }
#[inline(always)] #[inline(always)]
@ -442,7 +593,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_float(&self) -> Result<&Float, Error> { pub fn to_float(&self) -> Result<&Float, Error> {
self.as_float().ok_or_else(|| self.expected(ExpectedKind::Float)) self.as_float()
.ok_or_else(|| self.expected(ExpectedKind::Float))
} }
#[inline(always)] #[inline(always)]
@ -490,7 +642,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_double(&self) -> Result<&Double, Error> { pub fn to_double(&self) -> Result<&Double, Error> {
self.as_double().ok_or_else(|| self.expected(ExpectedKind::Double)) self.as_double()
.ok_or_else(|| self.expected(ExpectedKind::Double))
} }
#[inline(always)] #[inline(always)]
@ -538,7 +691,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_signedinteger(&self) -> Result<&SignedInteger, Error> { pub fn to_signedinteger(&self) -> Result<&SignedInteger, Error> {
self.as_signedinteger().ok_or_else(|| self.expected(ExpectedKind::SignedInteger)) self.as_signedinteger()
.ok_or_else(|| self.expected(ExpectedKind::SignedInteger))
} }
#[inline(always)] #[inline(always)]
@ -553,7 +707,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_i(&self) -> Result<i128, Error> { pub fn to_i(&self) -> Result<i128, Error> {
self.as_i().ok_or_else(|| self.expected(ExpectedKind::SignedIntegerI128)) self.as_i()
.ok_or_else(|| self.expected(ExpectedKind::SignedIntegerI128))
} }
#[inline(always)] #[inline(always)]
@ -568,38 +723,65 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_u(&self) -> Result<u128, Error> { pub fn to_u(&self) -> Result<u128, Error> {
self.as_u().ok_or_else(|| self.expected(ExpectedKind::SignedIntegerU128)) self.as_u()
.ok_or_else(|| self.expected(ExpectedKind::SignedIntegerU128))
} }
#[inline(always)] #[inline(always)]
pub fn as_u8(&self) -> Option<u8> { self.as_u().and_then(|i| i.to_u8()) } pub fn as_u8(&self) -> Option<u8> {
self.as_u().and_then(|i| i.to_u8())
}
#[inline(always)] #[inline(always)]
pub fn as_i8(&self) -> Option<i8> { self.as_i().and_then(|i| i.to_i8()) } pub fn as_i8(&self) -> Option<i8> {
self.as_i().and_then(|i| i.to_i8())
}
#[inline(always)] #[inline(always)]
pub fn as_u16(&self) -> Option<u16> { self.as_u().and_then(|i| i.to_u16()) } pub fn as_u16(&self) -> Option<u16> {
self.as_u().and_then(|i| i.to_u16())
}
#[inline(always)] #[inline(always)]
pub fn as_i16(&self) -> Option<i16> { self.as_i().and_then(|i| i.to_i16()) } pub fn as_i16(&self) -> Option<i16> {
self.as_i().and_then(|i| i.to_i16())
}
#[inline(always)] #[inline(always)]
pub fn as_u32(&self) -> Option<u32> { self.as_u().and_then(|i| i.to_u32()) } pub fn as_u32(&self) -> Option<u32> {
self.as_u().and_then(|i| i.to_u32())
}
#[inline(always)] #[inline(always)]
pub fn as_i32(&self) -> Option<i32> { self.as_i().and_then(|i| i.to_i32()) } pub fn as_i32(&self) -> Option<i32> {
self.as_i().and_then(|i| i.to_i32())
}
#[inline(always)] #[inline(always)]
pub fn as_u64(&self) -> Option<u64> { self.as_u().and_then(|i| i.to_u64()) } pub fn as_u64(&self) -> Option<u64> {
self.as_u().and_then(|i| i.to_u64())
}
#[inline(always)] #[inline(always)]
pub fn as_i64(&self) -> Option<i64> { self.as_i().and_then(|i| i.to_i64()) } pub fn as_i64(&self) -> Option<i64> {
self.as_i().and_then(|i| i.to_i64())
}
#[inline(always)] #[inline(always)]
pub fn as_u128(&self) -> Option<u128> { self.as_u().and_then(|i| i.to_u128()) } pub fn as_u128(&self) -> Option<u128> {
self.as_u().and_then(|i| i.to_u128())
}
#[inline(always)] #[inline(always)]
pub fn as_i128(&self) -> Option<i128> { self.as_i().and_then(|i| i.to_i128()) } pub fn as_i128(&self) -> Option<i128> {
self.as_i().and_then(|i| i.to_i128())
}
#[inline(always)] #[inline(always)]
pub fn as_usize(&self) -> Option<usize> { self.as_u().and_then(|i| i.to_usize()) } pub fn as_usize(&self) -> Option<usize> {
self.as_u().and_then(|i| i.to_usize())
}
#[inline(always)] #[inline(always)]
pub fn as_isize(&self) -> Option<isize> { self.as_i().and_then(|i| i.to_isize()) } pub fn as_isize(&self) -> Option<isize> {
self.as_i().and_then(|i| i.to_isize())
}
#[inline(always)] #[inline(always)]
pub fn to_i8(&self) -> Result<i8, Error> { pub fn to_i8(&self) -> Result<i8, Error> {
match self.as_i() { match self.as_i() {
Some(i) => i.to_i8().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_i8()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -607,7 +789,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_u8(&self) -> Result<u8, Error> { pub fn to_u8(&self) -> Result<u8, Error> {
match self.as_u() { match self.as_u() {
Some(i) => i.to_u8().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_u8()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -615,7 +799,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_i16(&self) -> Result<i16, Error> { pub fn to_i16(&self) -> Result<i16, Error> {
match self.as_i() { match self.as_i() {
Some(i) => i.to_i16().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_i16()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -623,7 +809,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_u16(&self) -> Result<u16, Error> { pub fn to_u16(&self) -> Result<u16, Error> {
match self.as_u() { match self.as_u() {
Some(i) => i.to_u16().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_u16()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -631,7 +819,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_i32(&self) -> Result<i32, Error> { pub fn to_i32(&self) -> Result<i32, Error> {
match self.as_i() { match self.as_i() {
Some(i) => i.to_i32().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_i32()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -639,7 +829,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_u32(&self) -> Result<u32, Error> { pub fn to_u32(&self) -> Result<u32, Error> {
match self.as_u() { match self.as_u() {
Some(i) => i.to_u32().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_u32()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -647,7 +839,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_i64(&self) -> Result<i64, Error> { pub fn to_i64(&self) -> Result<i64, Error> {
match self.as_i() { match self.as_i() {
Some(i) => i.to_i64().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_i64()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -655,7 +849,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_u64(&self) -> Result<u64, Error> { pub fn to_u64(&self) -> Result<u64, Error> {
match self.as_u() { match self.as_u() {
Some(i) => i.to_u64().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_u64()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -663,7 +859,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_i128(&self) -> Result<i128, Error> { pub fn to_i128(&self) -> Result<i128, Error> {
match self.as_i() { match self.as_i() {
Some(i) => i.to_i128().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_i128()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -671,7 +869,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_u128(&self) -> Result<u128, Error> { pub fn to_u128(&self) -> Result<u128, Error> {
match self.as_u() { match self.as_u() {
Some(i) => i.to_u128().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_u128()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -679,7 +879,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_isize(&self) -> Result<isize, Error> { pub fn to_isize(&self) -> Result<isize, Error> {
match self.as_i() { match self.as_i() {
Some(i) => i.to_isize().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_isize()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -687,7 +889,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_usize(&self) -> Result<usize, Error> { pub fn to_usize(&self) -> Result<usize, Error> {
match self.as_u() { match self.as_u() {
Some(i) => i.to_usize().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), Some(i) => i
.to_usize()
.ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
None => Err(self.expected(ExpectedKind::SignedInteger)), None => Err(self.expected(ExpectedKind::SignedInteger)),
} }
} }
@ -732,7 +936,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_string(&self) -> Result<&String, Error> { pub fn to_string(&self) -> Result<&String, Error> {
self.as_string().ok_or_else(|| self.expected(ExpectedKind::String)) self.as_string()
.ok_or_else(|| self.expected(ExpectedKind::String))
} }
#[inline(always)] #[inline(always)]
@ -773,7 +978,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_bytestring(&self) -> Result<&Vec<u8>, Error> { pub fn to_bytestring(&self) -> Result<&Vec<u8>, Error> {
self.as_bytestring().ok_or_else(|| self.expected(ExpectedKind::ByteString)) self.as_bytestring()
.ok_or_else(|| self.expected(ExpectedKind::ByteString))
} }
#[inline(always)] #[inline(always)]
@ -814,7 +1020,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_symbol(&self) -> Result<&String, Error> { pub fn to_symbol(&self) -> Result<&String, Error> {
self.as_symbol().ok_or_else(|| self.expected(ExpectedKind::Symbol)) self.as_symbol()
.ok_or_else(|| self.expected(ExpectedKind::Symbol))
} }
#[inline(always)] #[inline(always)]
@ -835,7 +1042,7 @@ impl<N: NestedValue> Value<N> {
match arity { match arity {
Some(expected) if r.arity() == expected => Some(r), Some(expected) if r.arity() == expected => Some(r),
Some(_other) => None, Some(_other) => None,
None => Some(r) None => Some(r),
} }
} else { } else {
None None
@ -856,7 +1063,7 @@ impl<N: NestedValue> Value<N> {
match arity { match arity {
Some(expected) if r.arity() == expected => Some(r), Some(expected) if r.arity() == expected => Some(r),
Some(_other) => None, Some(_other) => None,
None => Some(r) None => Some(r),
} }
} else { } else {
None None
@ -865,7 +1072,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_record(&self, arity: Option<usize>) -> Result<&Record<N>, Error> { pub fn to_record(&self, arity: Option<usize>) -> Result<&Record<N>, Error> {
self.as_record(arity).ok_or_else(|| self.expected(ExpectedKind::Record(arity))) self.as_record(arity)
.ok_or_else(|| self.expected(ExpectedKind::Record(arity)))
} }
#[inline(always)] #[inline(always)]
@ -892,18 +1100,14 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn as_simple_record(&self, label: &str, arity: Option<usize>) -> Option<&[N]> { pub fn as_simple_record(&self, label: &str, arity: Option<usize>) -> Option<&[N]> {
self.as_record(arity).and_then(|r| { self.as_record(arity).and_then(|r| match r.label().value() {
match r.label().value() { Value::Symbol(s) if s == label => Some(r.fields()),
Value::Symbol(s) if s == label => Some(r.fields()), _ => None,
_ => None
}
}) })
} }
#[inline(always)] #[inline(always)]
pub fn to_simple_record(&self, label: &str, arity: Option<usize>) -> pub fn to_simple_record(&self, label: &str, arity: Option<usize>) -> Result<&[N], Error> {
Result<&[N], Error>
{
self.as_simple_record(label, arity) self.as_simple_record(label, arity)
.ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label.to_owned(), arity))) .ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label.to_owned(), arity)))
} }
@ -914,8 +1118,8 @@ impl<N: NestedValue> Value<N> {
Some(_fs) => Ok(None), Some(_fs) => Ok(None),
None => match self.as_simple_record("Some", Some(1)) { None => match self.as_simple_record("Some", Some(1)) {
Some(fs) => Ok(Some(&fs[0])), Some(fs) => Ok(Some(&fs[0])),
None => Err(self.expected(ExpectedKind::Option)) None => Err(self.expected(ExpectedKind::Option)),
} },
} }
} }
@ -952,7 +1156,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_sequence(&self) -> Result<&Vec<N>, Error> { pub fn to_sequence(&self) -> Result<&Vec<N>, Error> {
self.as_sequence().ok_or_else(|| self.expected(ExpectedKind::Sequence)) self.as_sequence()
.ok_or_else(|| self.expected(ExpectedKind::Sequence))
} }
#[inline(always)] #[inline(always)]
@ -988,7 +1193,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_set(&self) -> Result<&Set<N>, Error> { pub fn to_set(&self) -> Result<&Set<N>, Error> {
self.as_set().ok_or_else(|| self.expected(ExpectedKind::Set)) self.as_set()
.ok_or_else(|| self.expected(ExpectedKind::Set))
} }
#[inline(always)] #[inline(always)]
@ -1024,7 +1230,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_dictionary(&self) -> Result<&Map<N, N>, Error> { pub fn to_dictionary(&self) -> Result<&Map<N, N>, Error> {
self.as_dictionary().ok_or_else(|| self.expected(ExpectedKind::Dictionary)) self.as_dictionary()
.ok_or_else(|| self.expected(ExpectedKind::Dictionary))
} }
#[inline(always)] #[inline(always)]
@ -1043,7 +1250,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)] #[inline(always)]
pub fn to_embedded(&self) -> Result<&N::Embedded, Error> { pub fn to_embedded(&self) -> Result<&N::Embedded, Error> {
self.as_embedded().ok_or_else(|| self.expected(ExpectedKind::Embedded)) self.as_embedded()
.ok_or_else(|| self.expected(ExpectedKind::Embedded))
} }
pub fn strip_annotations<M: NestedValue<Embedded = N::Embedded>>(&self) -> Value<M> { pub fn strip_annotations<M: NestedValue<Embedded = N::Embedded>>(&self) -> Value<M> {
@ -1055,21 +1263,28 @@ impl<N: NestedValue> Value<N> {
Value::String(s) => Value::String(s.clone()), Value::String(s) => Value::String(s.clone()),
Value::ByteString(v) => Value::ByteString(v.clone()), Value::ByteString(v) => Value::ByteString(v.clone()),
Value::Symbol(v) => Value::Symbol(v.clone()), Value::Symbol(v) => Value::Symbol(v.clone()),
Value::Record(r) => Value::Record(Record(r.fields_vec().iter().map( Value::Record(r) => Value::Record(Record(
|a| a.strip_annotations()).collect())), r.fields_vec()
Value::Sequence(v) => Value::Sequence(v.iter().map( .iter()
|a| a.strip_annotations()).collect()), .map(|a| a.strip_annotations())
Value::Set(v) => Value::Set(v.iter().map( .collect(),
|a| a.strip_annotations()).collect()), )),
Value::Dictionary(v) => Value::Dictionary(v.iter().map( Value::Sequence(v) => {
|(a,b)| (a.strip_annotations(), b.strip_annotations())).collect()), Value::Sequence(v.iter().map(|a| a.strip_annotations()).collect())
}
Value::Set(v) => Value::Set(v.iter().map(|a| a.strip_annotations()).collect()),
Value::Dictionary(v) => Value::Dictionary(
v.iter()
.map(|(a, b)| (a.strip_annotations(), b.strip_annotations()))
.collect(),
),
Value::Embedded(d) => Value::Embedded(d.clone()), Value::Embedded(d) => Value::Embedded(d.clone()),
} }
} }
pub fn copy_via<M: NestedValue, F, Err>(&self, f: &mut F) -> Result<Value<M>, Err> pub fn copy_via<M: NestedValue, F, Err>(&self, f: &mut F) -> Result<Value<M>, Err>
where where
F: FnMut(&N::Embedded) -> Result<Value<M>, Err> F: FnMut(&N::Embedded) -> Result<Value<M>, Err>,
{ {
Ok(match self { Ok(match self {
Value::Boolean(b) => Value::Boolean(*b), Value::Boolean(b) => Value::Boolean(*b),
@ -1079,35 +1294,52 @@ impl<N: NestedValue> Value<N> {
Value::String(s) => Value::String(s.clone()), Value::String(s) => Value::String(s.clone()),
Value::ByteString(v) => Value::ByteString(v.clone()), Value::ByteString(v) => Value::ByteString(v.clone()),
Value::Symbol(v) => Value::Symbol(v.clone()), Value::Symbol(v) => Value::Symbol(v.clone()),
Value::Record(r) => Value::Record(r) => Value::Record(Record(
Value::Record(Record(r.fields_vec().iter().map(|a| a.copy_via(f)) r.fields_vec()
.collect::<Result<Vec<_>, _>>()?)), .iter()
Value::Sequence(v) => Value::Sequence(v.iter().map(|a| a.copy_via(f)) .map(|a| a.copy_via(f))
.collect::<Result<Vec<_>, _>>()?), .collect::<Result<Vec<_>, _>>()?,
Value::Set(v) => Value::Set(v.iter().map(|a| a.copy_via(f)) )),
.collect::<Result<Set<_>, _>>()?), Value::Sequence(v) => Value::Sequence(
Value::Dictionary(v) => v.iter()
Value::Dictionary(v.iter().map(|(a,b)| Ok((a.copy_via(f)?, b.copy_via(f)?))) .map(|a| a.copy_via(f))
.collect::<Result<Map<_, _>, _>>()?), .collect::<Result<Vec<_>, _>>()?,
),
Value::Set(v) => Value::Set(
v.iter()
.map(|a| a.copy_via(f))
.collect::<Result<Set<_>, _>>()?,
),
Value::Dictionary(v) => Value::Dictionary(
v.iter()
.map(|(a, b)| Ok((a.copy_via(f)?, b.copy_via(f)?)))
.collect::<Result<Map<_, _>, _>>()?,
),
Value::Embedded(d) => f(d)?, Value::Embedded(d) => f(d)?,
}) })
} }
pub fn foreach_embedded<F, Err>(&self, f: &mut F) -> Result<(), Err> pub fn foreach_embedded<F, Err>(&self, f: &mut F) -> Result<(), Err>
where where
F: FnMut(&N::Embedded) -> Result<(), Err> F: FnMut(&N::Embedded) -> Result<(), Err>,
{ {
match self { match self {
Value::Boolean(_) | Value::Boolean(_)
Value::Float(_) | | Value::Float(_)
Value::Double(_) | | Value::Double(_)
Value::SignedInteger(_) | | Value::SignedInteger(_)
Value::String(_) | | Value::String(_)
Value::ByteString(_) | | Value::ByteString(_)
Value::Symbol(_) => Ok(()), | Value::Symbol(_) => Ok(()),
Value::Record(r) => Ok(for v in r.fields_vec() { v.foreach_embedded(f)? }), Value::Record(r) => Ok(for v in r.fields_vec() {
Value::Sequence(vs) => Ok(for v in vs { v.foreach_embedded(f)? }), v.foreach_embedded(f)?
Value::Set(vs) => Ok(for v in vs { v.foreach_embedded(f)? }), }),
Value::Sequence(vs) => Ok(for v in vs {
v.foreach_embedded(f)?
}),
Value::Set(vs) => Ok(for v in vs {
v.foreach_embedded(f)?
}),
Value::Dictionary(d) => Ok(for (k, v) in d { Value::Dictionary(d) => Ok(for (k, v) in d {
k.foreach_embedded(f)?; k.foreach_embedded(f)?;
v.foreach_embedded(f)?; v.foreach_embedded(f)?;
@ -1146,13 +1378,19 @@ impl<N: NestedValue> Index<&N> for Value<N> {
// This part is a terrible hack // This part is a terrible hack
impl serde::Serialize for UnwrappedIOValue { impl serde::Serialize for UnwrappedIOValue {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
super::magic::output_value(serializer, self.clone().wrap()) super::magic::output_value(serializer, self.clone().wrap())
} }
} }
impl<'de> serde::Deserialize<'de> for UnwrappedIOValue { impl<'de> serde::Deserialize<'de> for UnwrappedIOValue {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(super::magic::input_value::<'de, D>(deserializer)?.value_owned()) Ok(super::magic::input_value::<'de, D>(deserializer)?.value_owned())
} }
} }
@ -1189,12 +1427,14 @@ impl<N: NestedValue> Annotations<N> {
#[inline(always)] #[inline(always)]
pub fn to_vec(self) -> Vec<N> { pub fn to_vec(self) -> Vec<N> {
use std::ops::DerefMut; use std::ops::DerefMut;
self.0.map(|mut b| std::mem::take(b.deref_mut())).unwrap_or_default() self.0
.map(|mut b| std::mem::take(b.deref_mut()))
.unwrap_or_default()
} }
pub fn modify<F>(&mut self, f: F) -> &mut Self pub fn modify<F>(&mut self, f: F) -> &mut Self
where where
F: FnOnce(&mut Vec<N>) F: FnOnce(&mut Vec<N>),
{ {
match &mut self.0 { match &mut self.0 {
None => { None => {
@ -1217,13 +1457,15 @@ impl<N: NestedValue> Annotations<N> {
pub fn copy_via<M: NestedValue, F, Err>(&self, f: &mut F) -> Result<Annotations<M>, Err> pub fn copy_via<M: NestedValue, F, Err>(&self, f: &mut F) -> Result<Annotations<M>, Err>
where where
F: FnMut(&N::Embedded) -> Result<Value<M>, Err> F: FnMut(&N::Embedded) -> Result<Value<M>, Err>,
{ {
Ok(match &self.0 { Ok(match &self.0 {
None => None => Annotations(None),
Annotations(None), Some(b) => Annotations(Some(Box::new(
Some(b) => b.iter()
Annotations(Some(Box::new(b.iter().map(|a| a.copy_via(f)).collect::<Result<Vec<_>, _>>()?))), .map(|a| a.copy_via(f))
.collect::<Result<Vec<_>, _>>()?,
))),
}) })
} }
} }
@ -1358,7 +1600,9 @@ impl<D: Embeddable> NestedValue for RcValue<D> {
#[inline(always)] #[inline(always)]
fn value_owned(self) -> Value<Self> { fn value_owned(self) -> Value<Self> {
Rc::try_unwrap(self.0).unwrap_or_else(|_| panic!("value_owned on RcValue with refcount greater than one")).1 Rc::try_unwrap(self.0)
.unwrap_or_else(|_| panic!("value_owned on RcValue with refcount greater than one"))
.1
} }
} }
@ -1475,13 +1719,19 @@ impl std::str::FromStr for IOValue {
} }
impl serde::Serialize for IOValue { impl serde::Serialize for IOValue {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
super::magic::output_value(serializer, self.clone()) super::magic::output_value(serializer, self.clone())
} }
} }
impl<'de> serde::Deserialize<'de> for IOValue { impl<'de> serde::Deserialize<'de> for IOValue {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
super::magic::input_value(deserializer) super::magic::input_value(deserializer)
} }
} }
@ -1500,7 +1750,10 @@ impl<D: Embeddable> Debug for DummyValue<D> {
impl<D: Embeddable> DummyValue<D> { impl<D: Embeddable> DummyValue<D> {
#[inline(always)] #[inline(always)]
pub fn new() -> Self { pub fn new() -> Self {
DummyValue(AnnotatedValue::new(Annotations::empty(), Value::Boolean(false))) DummyValue(AnnotatedValue::new(
Annotations::empty(),
Value::Boolean(false),
))
} }
} }
@ -1514,22 +1767,22 @@ impl<D: Embeddable> NestedValue for DummyValue<D> {
#[inline(always)] #[inline(always)]
fn annotations(&self) -> &Annotations<Self> { fn annotations(&self) -> &Annotations<Self> {
&self.0.0 &self.0 .0
} }
#[inline(always)] #[inline(always)]
fn value(&self) -> &Value<Self> { fn value(&self) -> &Value<Self> {
&self.0.1 &self.0 .1
} }
#[inline(always)] #[inline(always)]
fn pieces(self) -> (Annotations<Self>, Value<Self>) { fn pieces(self) -> (Annotations<Self>, Value<Self>) {
(self.0.0, self.0.1) (self.0 .0, self.0 .1)
} }
#[inline(always)] #[inline(always)]
fn value_owned(self) -> Value<Self> { fn value_owned(self) -> Value<Self> {
self.0.1 self.0 .1
} }
} }

View File

@ -1,10 +1,13 @@
use crate::value::{Value, repr::Record, Map, IOValue}; use crate::value::{repr::Record, IOValue, Map, Value};
use serde::Serialize; use serde::Serialize;
#[derive(Debug)] #[derive(Debug)]
pub enum Error {} pub enum Error {}
impl serde::ser::Error for Error { impl serde::ser::Error for Error {
fn custom<T>(_: T) -> Self where T: std::fmt::Display { fn custom<T>(_: T) -> Self
where
T: std::fmt::Display,
{
unreachable!() unreachable!()
} }
} }
@ -103,7 +106,10 @@ impl serde::Serializer for Serializer {
Ok(Value::simple_record0("None").wrap()) Ok(Value::simple_record0("None").wrap())
} }
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize { fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok>
where
T: Serialize,
{
Ok(Value::simple_record1("Some", to_value(v)).wrap()) Ok(Value::simple_record1("Some", to_value(v)).wrap())
} }
@ -115,17 +121,18 @@ impl serde::Serializer for Serializer {
Ok(Value::simple_record0(name).wrap()) Ok(Value::simple_record0(name).wrap())
} }
fn serialize_unit_variant(self, fn serialize_unit_variant(
_name: &'static str, self,
_variant: u32, _name: &'static str,
variant_name: &'static str) -> _variant: u32,
Result<Self::Ok> variant_name: &'static str,
{ ) -> Result<Self::Ok> {
Ok(Value::simple_record0(variant_name).wrap()) Ok(Value::simple_record0(variant_name).wrap())
} }
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<Self::Ok>
Result<Self::Ok> where T: Serialize where
T: Serialize,
{ {
match super::magic::receive_output_value(name, value) { match super::magic::receive_output_value(name, value) {
Some(v) => Ok(v), Some(v) => Ok(v),
@ -136,57 +143,78 @@ impl serde::Serializer for Serializer {
} }
} }
fn serialize_newtype_variant<T: ?Sized>(self, fn serialize_newtype_variant<T: ?Sized>(
_name: &'static str, self,
_variant: u32, _name: &'static str,
variant_name: &'static str, _variant: u32,
value: &T) -> variant_name: &'static str,
Result<Self::Ok> where T: Serialize value: &T,
) -> Result<Self::Ok>
where
T: Serialize,
{ {
Ok(Value::simple_record1(variant_name, to_value(value)).wrap()) Ok(Value::simple_record1(variant_name, to_value(value)).wrap())
} }
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> { fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
let vec = match count { Some(n) => Vec::with_capacity(n), None => Vec::new() }; let vec = match count {
Some(n) => Vec::with_capacity(n),
None => Vec::new(),
};
Ok(SerializeSequence { vec }) Ok(SerializeSequence { vec })
} }
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> { fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> {
Ok(SerializeRecord { r: Value::simple_record("tuple", count) }) Ok(SerializeRecord {
r: Value::simple_record("tuple", count),
})
} }
fn serialize_tuple_struct(self, name: &'static str, count: usize) -> fn serialize_tuple_struct(
Result<Self::SerializeTupleStruct> self,
{ name: &'static str,
Ok(SerializeRecord { r: Value::simple_record(name, count) }) count: usize,
) -> Result<Self::SerializeTupleStruct> {
Ok(SerializeRecord {
r: Value::simple_record(name, count),
})
} }
fn serialize_tuple_variant(self, fn serialize_tuple_variant(
_name: &'static str, self,
_variant: u32, _name: &'static str,
variant_name: &'static str, _variant: u32,
count: usize) -> variant_name: &'static str,
Result<Self::SerializeTupleVariant> count: usize,
{ ) -> Result<Self::SerializeTupleVariant> {
Ok(SerializeRecord { r: Value::simple_record(variant_name, count) }) Ok(SerializeRecord {
r: Value::simple_record(variant_name, count),
})
} }
fn serialize_map(self, _count: Option<usize>) -> Result<Self::SerializeMap> { fn serialize_map(self, _count: Option<usize>) -> Result<Self::SerializeMap> {
Ok(SerializeDictionary { next_key: None, items: Map::new() }) Ok(SerializeDictionary {
next_key: None,
items: Map::new(),
})
} }
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> { fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
Ok(SerializeRecord { r: Value::simple_record(name, count) }) Ok(SerializeRecord {
r: Value::simple_record(name, count),
})
} }
fn serialize_struct_variant(self, fn serialize_struct_variant(
_name: &'static str, self,
_variant: u32, _name: &'static str,
variant_name: &'static str, _variant: u32,
count: usize) -> variant_name: &'static str,
Result<Self::SerializeStructVariant> count: usize,
{ ) -> Result<Self::SerializeStructVariant> {
Ok(SerializeRecord { r: Value::simple_record(variant_name, count) }) Ok(SerializeRecord {
r: Value::simple_record(variant_name, count),
})
} }
} }
@ -194,12 +222,18 @@ impl serde::ser::SerializeMap for SerializeDictionary {
type Ok = IOValue; type Ok = IOValue;
type Error = Error; type Error = Error;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize { fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>
where
T: Serialize,
{
self.next_key = Some(to_value(key)); self.next_key = Some(to_value(key));
Ok(()) Ok(())
} }
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: Serialize,
{
let key = self.next_key.take().unwrap(); let key = self.next_key.take().unwrap();
self.items.insert(key, to_value(value)); self.items.insert(key, to_value(value));
Ok(()) Ok(())
@ -212,7 +246,8 @@ impl serde::ser::SerializeMap for SerializeDictionary {
impl SerializeRecord { impl SerializeRecord {
fn push<T: ?Sized>(&mut self, value: &T) fn push<T: ?Sized>(&mut self, value: &T)
where T: Serialize where
T: Serialize,
{ {
self.r.fields_vec_mut().push(to_value(value)) self.r.fields_vec_mut().push(to_value(value))
} }
@ -227,7 +262,8 @@ impl serde::ser::SerializeStruct for SerializeRecord {
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()> fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize where
T: Serialize,
{ {
self.push(value); self.push(value);
Ok(()) Ok(())
@ -243,7 +279,8 @@ impl serde::ser::SerializeStructVariant for SerializeRecord {
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()> fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize where
T: Serialize,
{ {
self.push(value); self.push(value);
Ok(()) Ok(())
@ -258,7 +295,10 @@ impl serde::ser::SerializeTuple for SerializeRecord {
type Ok = IOValue; type Ok = IOValue;
type Error = Error; type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: Serialize,
{
self.push(value); self.push(value);
Ok(()) Ok(())
} }
@ -272,7 +312,10 @@ impl serde::ser::SerializeTupleStruct for SerializeRecord {
type Ok = IOValue; type Ok = IOValue;
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: Serialize,
{
self.push(value); self.push(value);
Ok(()) Ok(())
} }
@ -286,7 +329,10 @@ impl serde::ser::SerializeTupleVariant for SerializeRecord {
type Ok = IOValue; type Ok = IOValue;
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: Serialize,
{
self.push(value); self.push(value);
Ok(()) Ok(())
} }
@ -300,7 +346,10 @@ impl serde::ser::SerializeSeq for SerializeSequence {
type Ok = IOValue; type Ok = IOValue;
type Error = Error; type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: Serialize,
{
self.vec.push(to_value(value)); self.vec.push(to_value(value));
Ok(()) Ok(())
} }
@ -310,6 +359,9 @@ impl serde::ser::SerializeSeq for SerializeSequence {
} }
} }
pub fn to_value<T>(value: T) -> IOValue where T: Serialize { pub fn to_value<T>(value: T) -> IOValue
where
T: Serialize,
{
value.serialize(Serializer).unwrap() value.serialize(Serializer).unwrap()
} }

View File

@ -40,17 +40,40 @@ impl Ord for SignedInteger {
match self.repr() { match self.repr() {
SignedIntegerRepr::I128(i1) => match other.repr() { SignedIntegerRepr::I128(i1) => match other.repr() {
SignedIntegerRepr::I128(i2) => i1.cmp(i2), SignedIntegerRepr::I128(i2) => i1.cmp(i2),
SignedIntegerRepr::U128(_) => if *i1 < 0 { Ordering::Less } else { Ordering::Greater }, SignedIntegerRepr::U128(_) => {
SignedIntegerRepr::Big(n) => if n.is_negative() { Ordering::Less } else { Ordering::Greater }, if *i1 < 0 {
Ordering::Less
} else {
Ordering::Greater
}
}
SignedIntegerRepr::Big(n) => {
if n.is_negative() {
Ordering::Less
} else {
Ordering::Greater
}
}
}, },
SignedIntegerRepr::U128(u1) => match other.repr() { SignedIntegerRepr::U128(u1) => match other.repr() {
SignedIntegerRepr::I128(_) => Ordering::Greater, SignedIntegerRepr::I128(_) => Ordering::Greater,
SignedIntegerRepr::U128(u2) => u1.cmp(u2), SignedIntegerRepr::U128(u2) => u1.cmp(u2),
SignedIntegerRepr::Big(n) => if n.is_positive() { Ordering::Less } else { Ordering::Greater }, SignedIntegerRepr::Big(n) => {
if n.is_positive() {
Ordering::Less
} else {
Ordering::Greater
}
}
}, },
SignedIntegerRepr::Big(n1) => match other.repr() { SignedIntegerRepr::Big(n1) => match other.repr() {
SignedIntegerRepr::I128(_) | SignedIntegerRepr::I128(_) | SignedIntegerRepr::U128(_) => {
SignedIntegerRepr::U128(_) => if n1.is_negative() { Ordering::Less } else { Ordering::Greater }, if n1.is_negative() {
Ordering::Less
} else {
Ordering::Greater
}
}
SignedIntegerRepr::Big(n2) => n1.cmp(n2), SignedIntegerRepr::Big(n2) => n1.cmp(n2),
}, },
} }
@ -110,7 +133,7 @@ macro_rules! map_integral_type_to_signed_integer {
u128::try_from(v)?.try_into().map_err(|_| ()) u128::try_from(v)?.try_into().map_err(|_| ())
} }
} }
} };
} }
map_integral_type_to_signed_integer!(i8, u8); map_integral_type_to_signed_integer!(i8, u8);

View File

@ -14,22 +14,18 @@ impl<T> Suspendable<T> {
pub fn suspend(&mut self) -> Self { pub fn suspend(&mut self) -> Self {
match self { match self {
Suspendable::Active(_) => std::mem::replace(self, Suspendable::Suspended), Suspendable::Active(_) => std::mem::replace(self, Suspendable::Suspended),
Suspendable::Suspended => Suspendable::Suspended => panic!("Attempt to suspend suspended Suspendable"),
panic!("Attempt to suspend suspended Suspendable"),
} }
} }
#[inline(always)] #[inline(always)]
pub fn resume(&mut self, other: Self) { pub fn resume(&mut self, other: Self) {
match self { match self {
Suspendable::Suspended => Suspendable::Suspended => match other {
match other { Suspendable::Active(_) => *self = other,
Suspendable::Active(_) => *self = other, Suspendable::Suspended => panic!("Attempt to resume from suspended Suspendable"),
Suspendable::Suspended => },
panic!("Attempt to resume from suspended Suspendable"), Suspendable::Active(_) => panic!("Attempt to resume non-suspended Suspendable"),
},
Suspendable::Active(_) =>
panic!("Attempt to resume non-suspended Suspendable"),
} }
} }
@ -37,8 +33,7 @@ impl<T> Suspendable<T> {
pub fn take(self) -> T { pub fn take(self) -> T {
match self { match self {
Suspendable::Active(t) => t, Suspendable::Active(t) => t,
Suspendable::Suspended => Suspendable::Suspended => panic!("Attempt to take from suspended Suspendable"),
panic!("Attempt to take from suspended Suspendable"),
} }
} }
} }
@ -49,7 +44,7 @@ impl<T> Deref for Suspendable<T> {
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
match self { match self {
Suspendable::Suspended => panic!("Suspended Suspendable at deref"), Suspendable::Suspended => panic!("Suspended Suspendable at deref"),
Suspendable::Active(t) => t Suspendable::Active(t) => t,
} }
} }
} }
@ -59,7 +54,7 @@ impl<T> DerefMut for Suspendable<T> {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
match self { match self {
Suspendable::Suspended => panic!("Empty Suspendable at deref_mut"), Suspendable::Suspended => panic!("Empty Suspendable at deref_mut"),
Suspendable::Active(t) => t Suspendable::Active(t) => t,
} }
} }
} }

View File

@ -1,12 +1,16 @@
use crate::error::Error;
use crate::error::ExpectedKind;
use crate::error::Received;
use crate::error::io_syntax_error; use crate::error::io_syntax_error;
use crate::error::is_eof_io_error; use crate::error::is_eof_io_error;
use crate::error::syntax_error; use crate::error::syntax_error;
use crate::error::Error;
use crate::error::ExpectedKind;
use crate::error::Received;
use crate::hex; use crate::hex;
use crate::value::boundary as B;
use crate::value::reader::BinarySource;
use crate::value::reader::ReaderResult;
use crate::value::repr::Annotations;
use crate::value::CompoundClass; use crate::value::CompoundClass;
use crate::value::DomainParse; use crate::value::DomainParse;
use crate::value::DummyValue; use crate::value::DummyValue;
@ -21,10 +25,6 @@ use crate::value::Set;
use crate::value::Token; use crate::value::Token;
use crate::value::Value; use crate::value::Value;
use crate::value::ViaCodec; use crate::value::ViaCodec;
use crate::value::boundary as B;
use crate::value::reader::BinarySource;
use crate::value::reader::ReaderResult;
use crate::value::repr::Annotations;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -49,7 +49,7 @@ fn append_codepoint(bs: &mut Vec<u8>, n: u32) -> io::Result<()> {
let c = char::from_u32(n).ok_or_else(|| io_syntax_error("Bad code point"))?; let c = char::from_u32(n).ok_or_else(|| io_syntax_error("Bad code point"))?;
let mut buf = [0; 4]; let mut buf = [0; 4];
let _ = c.encode_utf8(&mut buf); let _ = c.encode_utf8(&mut buf);
bs.extend(&buf[0 .. c.len_utf8()]); bs.extend(&buf[0..c.len_utf8()]);
Ok(()) Ok(())
} }
@ -95,7 +95,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
fn expected<N: NestedValue<Embedded = D>>(&mut self, k: ExpectedKind) -> Error { fn expected<N: NestedValue<Embedded = D>>(&mut self, k: ExpectedKind) -> Error {
match Reader::<N>::demand_next(self, true) { match Reader::<N>::demand_next(self, true) {
Ok(v) => Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))), Ok(v) => Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))),
Err(e) => e.into() Err(e) => e.into(),
} }
} }
@ -104,8 +104,14 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
loop { loop {
self.skip_whitespace(); self.skip_whitespace();
match self.peek()? { match self.peek()? {
b';' => { self.skip()?; vs.push(N::new(self.comment_line()?)) } b';' => {
b'@' => { self.skip()?; vs.push(self.demand_next(true)?) } self.skip()?;
vs.push(N::new(self.comment_line()?))
}
b'@' => {
self.skip()?;
vs.push(self.demand_next(true)?)
}
_ => return Ok(vs), _ => return Ok(vs),
} }
} }
@ -115,8 +121,14 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
loop { loop {
self.skip_whitespace(); self.skip_whitespace();
match self.peek()? { match self.peek()? {
b';' => { self.skip()?; self.comment_line()?; }, b';' => {
b'@' => { self.skip()?; Reader::<DummyValue<D>>::skip_value(self)?; }, self.skip()?;
self.comment_line()?;
}
b'@' => {
self.skip()?;
Reader::<DummyValue<D>>::skip_value(self)?;
}
_ => return Ok(()), _ => return Ok(()),
} }
} }
@ -142,16 +154,22 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
fn read_hex_float<N: NestedValue>(&mut self, bytecount: usize) -> io::Result<N> { fn read_hex_float<N: NestedValue>(&mut self, bytecount: usize) -> io::Result<N> {
if self.next_byte()? != b'"' { if self.next_byte()? != b'"' {
return Err(io_syntax_error("Missing open-double-quote in hex-encoded floating-point number")); return Err(io_syntax_error(
"Missing open-double-quote in hex-encoded floating-point number",
));
} }
let bs = self.read_hex_binary()?; let bs = self.read_hex_binary()?;
if bs.len() != bytecount { if bs.len() != bytecount {
return Err(io_syntax_error("Incorrect number of bytes in hex-encoded floating-point number")); return Err(io_syntax_error(
"Incorrect number of bytes in hex-encoded floating-point number",
));
} }
match bytecount { match bytecount {
4 => Ok(Value::from(f32::from_bits(u32::from_be_bytes(bs.try_into().unwrap()))).wrap()), 4 => Ok(Value::from(f32::from_bits(u32::from_be_bytes(bs.try_into().unwrap()))).wrap()),
8 => Ok(Value::from(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap()))).wrap()), 8 => Ok(Value::from(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap()))).wrap()),
_ => Err(io_syntax_error("Unsupported byte count in hex-encoded floating-point number")), _ => Err(io_syntax_error(
"Unsupported byte count in hex-encoded floating-point number",
)),
} }
} }
@ -187,13 +205,11 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
fn hexnum(&mut self, count: usize) -> io::Result<u32> { fn hexnum(&mut self, count: usize) -> io::Result<u32> {
let mut v: u32 = 0; let mut v: u32 = 0;
for _ in 0 .. count { for _ in 0..count {
let c = self.next_byte()?; let c = self.next_byte()?;
match (c as char).to_digit(16) { match (c as char).to_digit(16) {
Some(d) => Some(d) => v = v << 4 | d,
v = v << 4 | d, None => return Err(io_syntax_error("Bad hex escape")),
None =>
return Err(io_syntax_error("Bad hex escape")),
} }
} }
Ok(v) Ok(v)
@ -207,7 +223,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
b'u', b'u',
|bs, r| { |bs, r| {
let n1 = r.hexnum(4)?; let n1 = r.hexnum(4)?;
if (0xd800 ..= 0xdbff).contains(&n1) { if (0xd800..=0xdbff).contains(&n1) {
let mut ok = true; let mut ok = true;
ok = ok && r.next_byte()? == b'\\'; ok = ok && r.next_byte()? == b'\\';
ok = ok && r.next_byte()? == b'u'; ok = ok && r.next_byte()? == b'u';
@ -215,7 +231,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
Err(io_syntax_error("Missing second half of surrogate pair")) Err(io_syntax_error("Missing second half of surrogate pair"))
} else { } else {
let n2 = r.hexnum(4)?; let n2 = r.hexnum(4)?;
if (0xdc00 ..= 0xdfff).contains(&n2) { if (0xdc00..=0xdfff).contains(&n2) {
let n = ((n1 - 0xd800) << 10) + (n2 - 0xdc00) + 0x10000; let n = ((n1 - 0xd800) << 10) + (n2 - 0xdc00) + 0x10000;
append_codepoint(bs, n) append_codepoint(bs, n)
} else { } else {
@ -225,16 +241,20 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
} else { } else {
append_codepoint(bs, n1) append_codepoint(bs, n1)
} }
})?) },
)?)
} }
fn read_literal_binary<N: NestedValue>(&mut self) -> io::Result<N> { fn read_literal_binary<N: NestedValue>(&mut self) -> io::Result<N> {
Ok(N::new(&self.read_stringlike( Ok(N::new(
Vec::new(), &self.read_stringlike(
|bs, b| Ok(bs.push(b)), Vec::new(),
b'"', |bs, b| Ok(bs.push(b)),
b'x', b'"',
|bs, r| Ok(bs.push(r.hexnum(2)? as u8)))?[..])) b'x',
|bs, r| Ok(bs.push(r.hexnum(2)? as u8)),
)?[..],
))
} }
fn read_hex_binary(&mut self) -> io::Result<Vec<u8>> { fn read_hex_binary(&mut self) -> io::Result<Vec<u8>> {
@ -264,14 +284,24 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
.map_err(|_| io_syntax_error("Invalid base64 character"))?; .map_err(|_| io_syntax_error("Invalid base64 character"))?;
return Ok(N::new(&bs[..])); return Ok(N::new(&bs[..]));
} }
if c == b'-' { c = b'+'; } if c == b'-' {
if c == b'_' { c = b'/'; } c = b'+';
if c == b'=' { continue; } }
if c == b'_' {
c = b'/';
}
if c == b'=' {
continue;
}
bs.push(c); bs.push(c);
} }
} }
fn upto<N: NestedValue<Embedded = D>>(&mut self, delimiter: u8, read_annotations: bool) -> io::Result<Vec<N>> { fn upto<N: NestedValue<Embedded = D>>(
&mut self,
delimiter: u8,
read_annotations: bool,
) -> io::Result<Vec<N>> {
let mut vs = Vec::new(); let mut vs = Vec::new();
loop { loop {
self.skip_whitespace(); self.skip_whitespace();
@ -283,7 +313,10 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
} }
} }
fn read_dictionary<N: NestedValue<Embedded = D>>(&mut self, read_annotations: bool) -> io::Result<N> { fn read_dictionary<N: NestedValue<Embedded = D>>(
&mut self,
read_annotations: bool,
) -> io::Result<N> {
let mut d = Map::new(); let mut d = Map::new();
loop { loop {
self.skip_whitespace(); self.skip_whitespace();
@ -303,44 +336,51 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
fn read_raw_symbol_or_number<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> { fn read_raw_symbol_or_number<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
lazy_static! { lazy_static! {
static ref NUMBER_RE: regex::Regex = regex::Regex::new( static ref NUMBER_RE: regex::Regex =
r"^([-+]?\d+)(((\.\d+([eE][-+]?\d+)?)|([eE][-+]?\d+))([fF]?))?$").unwrap(); regex::Regex::new(r"^([-+]?\d+)(((\.\d+([eE][-+]?\d+)?)|([eE][-+]?\d+))([fF]?))?$")
.unwrap();
} }
loop { loop {
let c = match self.peek() { let c = match self.peek() {
Err(e) if is_eof_io_error(&e) => b' ', Err(e) if is_eof_io_error(&e) => b' ',
Err(e) => return Err(e)?, Err(e) => return Err(e)?,
Ok(c) if (c as char).is_whitespace() => b' ', Ok(c) if (c as char).is_whitespace() => b' ',
Ok(c) => c Ok(c) => c,
}; };
match c { match c {
b'(' | b')' | b'{' | b'}' | b'[' | b']' | b'<' | b'>' | b'(' | b')' | b'{' | b'}' | b'[' | b']' | b'<' | b'>' | b'"' | b';' | b','
b'"' | b';' | b',' | b'@' | b'#' | b':' | b'|' | b' ' => { | b'@' | b'#' | b':' | b'|' | b' ' => {
let s = decode_utf8(bs)?; let s = decode_utf8(bs)?;
return match NUMBER_RE.captures(&s) { return match NUMBER_RE.captures(&s) {
None => Ok(N::symbol(&s)), None => Ok(N::symbol(&s)),
Some(m) => match m.get(2) { Some(m) => match m.get(2) {
None => Ok(N::new(s.parse::<BigInt>().map_err( None => Ok(N::new(s.parse::<BigInt>().map_err(|_| {
|_| io_syntax_error(&format!( io_syntax_error(&format!("Invalid signed-integer number: {:?}", s))
"Invalid signed-integer number: {:?}", s)))?)), })?)),
Some(_) => { Some(_) => {
if let Some(maybe_f) = m.get(7) { if let Some(maybe_f) = m.get(7) {
let s = m[1].to_owned() + &m[3]; let s = m[1].to_owned() + &m[3];
if maybe_f.range().is_empty() { if maybe_f.range().is_empty() {
Ok(N::new(s.parse::<f64>().map_err( Ok(N::new(s.parse::<f64>().map_err(|_| {
|_| io_syntax_error(&format!( io_syntax_error(&format!(
"Invalid double-precision number: {:?}", s)))?)) "Invalid double-precision number: {:?}",
s
))
})?))
} else { } else {
Ok(N::new(s.parse::<f32>().map_err( Ok(N::new(s.parse::<f32>().map_err(|_| {
|_| io_syntax_error(&format!( io_syntax_error(&format!(
"Invalid single-precision number: {:?}", s)))?)) "Invalid single-precision number: {:?}",
s
))
})?))
} }
} else { } else {
panic!("Internal error: cannot analyze number {:?}", s) panic!("Internal error: cannot analyze number {:?}", s)
} }
} }
} },
} };
} }
c => { c => {
self.skip()?; self.skip()?;
@ -351,8 +391,8 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
} }
} }
impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'de>> impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'de>> Reader<'de, N>
Reader<'de, N> for TextReader<'de, 'src, N::Embedded, Dec, S> for TextReader<'de, 'src, N::Embedded, Dec, S>
{ {
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> { fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
self.skip_whitespace(); self.skip_whitespace();
@ -383,14 +423,18 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
} }
} }
b':' => { b':' => {
return Err(io_syntax_error("Unexpected key/value separator between items")); return Err(io_syntax_error(
"Unexpected key/value separator between items",
));
} }
b'#' => { b'#' => {
self.skip()?; self.skip()?;
match self.next_byte()? { match self.next_byte()? {
b'f' => N::new(false), b'f' => N::new(false),
b't' => N::new(true), b't' => N::new(true),
b'{' => N::new(Set::from_iter(self.upto(b'}', read_annotations)?.into_iter())), b'{' => N::new(Set::from_iter(
self.upto(b'}', read_annotations)?.into_iter(),
)),
b'"' => self.read_literal_binary()?, b'"' => self.read_literal_binary()?,
b'x' => match self.next_byte()? { b'x' => match self.next_byte()? {
b'"' => N::new(&self.read_hex_binary()?[..]), b'"' => N::new(&self.read_hex_binary()?[..]),
@ -403,7 +447,9 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
let v = self.next_iovalue(read_annotations)?; let v = self.next_iovalue(read_annotations)?;
Value::Embedded(self.dec.parse_embedded(&v)?).wrap() Value::Embedded(self.dec.parse_embedded(&v)?).wrap()
} }
other => return Err(io_syntax_error(&format!("Invalid # syntax: {:?}", other))), other => {
return Err(io_syntax_error(&format!("Invalid # syntax: {:?}", other)))
}
} }
} }
b'<' => { b'<' => {
@ -434,7 +480,9 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> { fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> {
self.skip_annotations()?; self.skip_annotations()?;
if self.peek()? != b'<' { return Err(self.expected::<N>(ExpectedKind::Record(arity))); } if self.peek()? != b'<' {
return Err(self.expected::<N>(ExpectedKind::Record(arity)));
}
self.skip()?; self.skip()?;
let mut b = B::Type::default(); let mut b = B::Type::default();
Reader::<N>::ensure_more_expected(self, &mut b, &B::Item::RecordLabel)?; Reader::<N>::ensure_more_expected(self, &mut b, &B::Item::RecordLabel)?;
@ -458,7 +506,9 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
fn open_sequence(&mut self) -> ReaderResult<()> { fn open_sequence(&mut self) -> ReaderResult<()> {
self.skip_annotations()?; self.skip_annotations()?;
if self.peek()? != b'[' { return Err(self.expected::<N>(ExpectedKind::Sequence)); } if self.peek()? != b'[' {
return Err(self.expected::<N>(ExpectedKind::Sequence));
}
self.skip()?; self.skip()?;
Ok(()) Ok(())
} }
@ -479,7 +529,9 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
fn open_dictionary(&mut self) -> ReaderResult<()> { fn open_dictionary(&mut self) -> ReaderResult<()> {
self.skip_annotations()?; self.skip_annotations()?;
if self.peek()? != b'{' { return Err(self.expected::<N>(ExpectedKind::Dictionary)); } if self.peek()? != b'{' {
return Err(self.expected::<N>(ExpectedKind::Dictionary));
}
self.skip()?; self.skip()?;
Ok(()) Ok(())
} }
@ -495,7 +547,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
if self.next_byte()? != b':' { if self.next_byte()? != b':' {
return Err(syntax_error("Missing expected key/value separator")); return Err(syntax_error("Missing expected key/value separator"));
} }
}, }
_ => (), _ => (),
} }
Ok(()) Ok(())

View File

@ -1,11 +1,11 @@
use crate::hex::HexFormatter; use crate::hex::HexFormatter;
use crate::value::suspendable::Suspendable;
use crate::value::writer::CompoundWriter;
use crate::value::DomainEncode; use crate::value::DomainEncode;
use crate::value::IOValue; use crate::value::IOValue;
use crate::value::IOValueDomainCodec; use crate::value::IOValueDomainCodec;
use crate::value::NestedValue; use crate::value::NestedValue;
use crate::value::Writer; use crate::value::Writer;
use crate::value::suspendable::Suspendable;
use crate::value::writer::CompoundWriter;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -44,10 +44,12 @@ impl TextWriter<&mut Vec<u8>> {
) -> io::Result<()> { ) -> io::Result<()> {
let mut buf: Vec<u8> = Vec::new(); let mut buf: Vec<u8> = Vec::new();
let mut w = TextWriter::new(&mut buf); let mut w = TextWriter::new(&mut buf);
if f.alternate() { w.indentation = 4 } if f.alternate() {
w.indentation = 4
}
w.write_value(enc, v)?; w.write_value(enc, v)?;
f.write_str(std::str::from_utf8(&buf).expect("valid UTF-8 from TextWriter")).map_err( f.write_str(std::str::from_utf8(&buf).expect("valid UTF-8 from TextWriter"))
|_| io::Error::new(io::ErrorKind::Other, "could not append to Formatter")) .map_err(|_| io::Error::new(io::ErrorKind::Other, "could not append to Formatter"))
} }
pub fn encode<N: NestedValue, Enc: DomainEncode<N::Embedded>>( pub fn encode<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
@ -86,19 +88,20 @@ impl<W: io::Write> TextWriter<W> {
} }
pub fn suspend(&mut self) -> Self { pub fn suspend(&mut self) -> Self {
TextWriter { w: self.w.suspend(), indent: self.indent.clone(), .. *self } TextWriter {
w: self.w.suspend(),
indent: self.indent.clone(),
..*self
}
} }
pub fn resume(&mut self, other: Self) { pub fn resume(&mut self, other: Self) {
self.w.resume(other.w) self.w.resume(other.w)
} }
pub fn write_stringlike_char_fallback<F>( pub fn write_stringlike_char_fallback<F>(&mut self, c: char, f: F) -> io::Result<()>
&mut self, where
c: char, F: FnOnce(&mut W, char) -> io::Result<()>,
f: F,
) -> io::Result<()> where
F: FnOnce(&mut W, char) -> io::Result<()>
{ {
match c { match c {
'\\' => write!(self.w, "\\\\"), '\\' => write!(self.w, "\\\\"),
@ -116,7 +119,7 @@ impl<W: io::Write> TextWriter<W> {
} }
pub fn add_indent(&mut self) { pub fn add_indent(&mut self) {
for _ in 0 .. self.indentation { for _ in 0..self.indentation {
self.indent.push(' ') self.indent.push(' ')
} }
} }
@ -152,28 +155,21 @@ impl<W: io::Write> CompoundWriter for TextWriter<W> {
#[inline] #[inline]
fn boundary(&mut self, b: &B::Type) -> io::Result<()> { fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
match (b.closing.as_ref(), b.opening.as_ref()) { match (b.closing.as_ref(), b.opening.as_ref()) {
(None, Some(B::Item::RecordLabel)) | (None, Some(B::Item::RecordLabel))
(Some(B::Item::RecordLabel), None) | | (Some(B::Item::RecordLabel), None)
(Some(B::Item::RecordField), None) => | (Some(B::Item::RecordField), None) => return Ok(()),
return Ok(()), (_, Some(B::Item::RecordField)) => return write!(self.w, " "),
(_, Some(B::Item::RecordField)) =>
return write!(self.w, " "),
(Some(B::Item::DictionaryKey), Some(B::Item::DictionaryValue)) => { (Some(B::Item::DictionaryKey), Some(B::Item::DictionaryValue)) => {
return write!(self.w, ": ") return write!(self.w, ": ")
} }
(None, Some(B::Item::Annotation)) => { (None, Some(B::Item::Annotation)) => return write!(self.w, "@"),
return write!(self.w, "@") (Some(_), Some(B::Item::Annotation)) => return write!(self.w, " @"),
}
(Some(_), Some(B::Item::Annotation)) => {
return write!(self.w, " @")
}
(Some(B::Item::Annotation), Some(B::Item::AnnotatedValue)) => { (Some(B::Item::Annotation), Some(B::Item::AnnotatedValue)) => {
return write!(self.w, " ") return write!(self.w, " ")
} }
(Some(B::Item::AnnotatedValue), None) => (Some(B::Item::AnnotatedValue), None) => return Ok(()),
return Ok(()),
_ => (), _ => (),
} }
@ -183,7 +179,7 @@ impl<W: io::Write> CompoundWriter for TextWriter<W> {
(None, Some(_)) => { (None, Some(_)) => {
self.add_indent(); self.add_indent();
self.indent()? self.indent()?
}, }
(Some(_), Some(_)) => { (Some(_), Some(_)) => {
match self.comma_style { match self.comma_style {
CommaStyle::Separating | CommaStyle::Terminating => write!(self.w, ",")?, CommaStyle::Separating | CommaStyle::Terminating => write!(self.w, ",")?,
@ -206,10 +202,11 @@ impl<W: io::Write> CompoundWriter for TextWriter<W> {
} }
macro_rules! simple_writer_method { macro_rules! simple_writer_method {
($n:ident, $argty:ty) => ($n:ident, $argty:ty) => {
(fn $n (&mut self, v: $argty) -> io::Result<()> { fn $n(&mut self, v: $argty) -> io::Result<()> {
write!(self.w, "{}", v) write!(self.w, "{}", v)
}); }
};
} }
impl<W: io::Write> Writer for TextWriter<W> { impl<W: io::Write> Writer for TextWriter<W> {
@ -235,8 +232,11 @@ impl<W: io::Write> Writer for TextWriter<W> {
fn write_f32(&mut self, v: f32) -> io::Result<()> { fn write_f32(&mut self, v: f32) -> io::Result<()> {
if v.is_nan() || v.is_infinite() { if v.is_nan() || v.is_infinite() {
write!(self.w, "#xf\"{}\"", write!(
HexFormatter::Packed.encode(&u32::to_be_bytes(f32::to_bits(v)))) self.w,
"#xf\"{}\"",
HexFormatter::Packed.encode(&u32::to_be_bytes(f32::to_bits(v)))
)
} else { } else {
dtoa::write(&mut *self.w, v)?; dtoa::write(&mut *self.w, v)?;
write!(self.w, "f") write!(self.w, "f")
@ -245,8 +245,11 @@ impl<W: io::Write> Writer for TextWriter<W> {
fn write_f64(&mut self, v: f64) -> io::Result<()> { fn write_f64(&mut self, v: f64) -> io::Result<()> {
if v.is_nan() || v.is_infinite() { if v.is_nan() || v.is_infinite() {
write!(self.w, "#xd\"{}\"", write!(
HexFormatter::Packed.encode(&u64::to_be_bytes(f64::to_bits(v)))) self.w,
"#xd\"{}\"",
HexFormatter::Packed.encode(&u64::to_be_bytes(f64::to_bits(v)))
)
} else { } else {
dtoa::write(&mut *self.w, v)?; dtoa::write(&mut *self.w, v)?;
Ok(()) Ok(())
@ -278,7 +281,11 @@ impl<W: io::Write> Writer for TextWriter<W> {
} }
fn write_bytes(&mut self, v: &[u8]) -> io::Result<()> { fn write_bytes(&mut self, v: &[u8]) -> io::Result<()> {
write!(self.w, "#[{}]", base64::encode_config(v, base64::STANDARD_NO_PAD)) write!(
self.w,
"#[{}]",
base64::encode_config(v, base64::STANDARD_NO_PAD)
)
} }
fn write_symbol(&mut self, v: &str) -> io::Result<()> { fn write_symbol(&mut self, v: &str) -> io::Result<()> {

View File

@ -1,9 +1,9 @@
use super::boundary as B;
use super::repr::{Double, Float, NestedValue, Value};
use super::signed_integer::SignedIntegerRepr;
use super::DomainEncode;
use num::bigint::BigInt; use num::bigint::BigInt;
use std::io; use std::io;
use super::DomainEncode;
use super::boundary as B;
use super::signed_integer::SignedIntegerRepr;
use super::repr::{Value, NestedValue, Float, Double};
pub trait CompoundWriter: Writer { pub trait CompoundWriter: Writer {
fn boundary(&mut self, b: &B::Type) -> io::Result<()>; fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
@ -101,7 +101,7 @@ pub trait Writer: Sized {
SignedIntegerRepr::I128(i) => self.write_i128(*i), SignedIntegerRepr::I128(i) => self.write_i128(*i),
SignedIntegerRepr::U128(u) => self.write_u128(*u), SignedIntegerRepr::U128(u) => self.write_u128(*u),
SignedIntegerRepr::Big(n) => self.write_int(n), SignedIntegerRepr::Big(n) => self.write_int(n),
} },
Value::String(s) => self.write_string(s), Value::String(s) => self.write_string(s),
Value::ByteString(bs) => self.write_bytes(bs), Value::ByteString(bs) => self.write_bytes(bs),
Value::Symbol(s) => self.write_symbol(s), Value::Symbol(s) => self.write_symbol(s),

View File

@ -3,7 +3,7 @@ use preserves::value::{IOValue, Map};
#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct TestCases { pub struct TestCases {
pub tests: Map<Symbol, TestCase> pub tests: Map<Symbol, TestCase>,
} }
#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]

View File

@ -1,23 +1,27 @@
use preserves::error::{is_eof_io_error, is_syntax_io_error}; use preserves::error::{is_eof_io_error, is_syntax_io_error};
use preserves::symbol::Symbol; use preserves::symbol::Symbol;
use preserves::value::de::from_value as deserialize_from_value;
use preserves::value::BinarySource; use preserves::value::BinarySource;
use preserves::value::BytesBinarySource; use preserves::value::BytesBinarySource;
use preserves::value::IOBinarySource; use preserves::value::IOBinarySource;
use preserves::value::IOValue; use preserves::value::IOValue;
use preserves::value::PackedWriter; use preserves::value::PackedWriter;
use preserves::value::Reader; use preserves::value::Reader;
use preserves::value::de::from_value as deserialize_from_value;
use std::iter::Iterator;
use std::io; use std::io;
use std::iter::Iterator;
mod samples; mod samples;
use samples::*; use samples::*;
fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> { fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
BytesBinarySource::new(bytes).packed_iovalues().configured(true).collect() BytesBinarySource::new(bytes)
.packed_iovalues()
.configured(true)
.collect()
} }
#[test] fn compare_text_with_packed() -> io::Result<()> { #[test]
fn compare_text_with_packed() -> io::Result<()> {
use io::prelude::*; use io::prelude::*;
let from_text = { let from_text = {
let mut fh = std::fs::File::open("../../../tests/samples.pr").unwrap(); let mut fh = std::fs::File::open("../../../tests/samples.pr").unwrap();
@ -25,18 +29,22 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
fh.read_to_string(&mut contents)?; fh.read_to_string(&mut contents)?;
preserves::value::TextReader::new( preserves::value::TextReader::new(
&mut BytesBinarySource::new(contents.as_bytes()), &mut BytesBinarySource::new(contents.as_bytes()),
preserves::value::ViaCodec::new(preserves::value::IOValueDomainCodec)) preserves::value::ViaCodec::new(preserves::value::IOValueDomainCodec),
.next_iovalue(true)? )
.next_iovalue(true)?
}; };
let from_packed = { let from_packed = {
let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap(); let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap();
IOBinarySource::new(&mut fh).packed_iovalues().demand_next(true)? IOBinarySource::new(&mut fh)
.packed_iovalues()
.demand_next(true)?
}; };
assert_eq!(from_text, from_packed); assert_eq!(from_text, from_packed);
Ok(()) Ok(())
} }
#[test] fn compare_deserialize_text_with_packed() -> io::Result<()> { #[test]
fn compare_deserialize_text_with_packed() -> io::Result<()> {
use io::prelude::*; use io::prelude::*;
let from_text = { let from_text = {
let mut fh = std::fs::File::open("../../../tests/samples.pr").unwrap(); let mut fh = std::fs::File::open("../../../tests/samples.pr").unwrap();
@ -54,7 +62,8 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
Ok(()) Ok(())
} }
#[test] fn read_write_read_text() -> io::Result<()> { #[test]
fn read_write_read_text() -> io::Result<()> {
use io::prelude::*; use io::prelude::*;
let from_text = { let from_text = {
let mut fh = std::fs::File::open("../../../tests/samples.pr").unwrap(); let mut fh = std::fs::File::open("../../../tests/samples.pr").unwrap();
@ -82,7 +91,8 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
Ok(()) Ok(())
} }
#[test] fn deserialize_serialize_deserialize_text() -> io::Result<()> { #[test]
fn deserialize_serialize_deserialize_text() -> io::Result<()> {
use io::prelude::*; use io::prelude::*;
let from_text = { let from_text = {
let mut fh = std::fs::File::open("../../../tests/samples.pr").unwrap(); let mut fh = std::fs::File::open("../../../tests/samples.pr").unwrap();
@ -102,7 +112,8 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
Ok(()) Ok(())
} }
#[test] fn run() -> io::Result<()> { #[test]
fn run() -> io::Result<()> {
let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap(); let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap();
let mut src = IOBinarySource::new(&mut fh); let mut src = IOBinarySource::new(&mut fh);
let mut d = src.packed_iovalues().configured(true); let mut d = src.packed_iovalues().configured(true);
@ -112,7 +123,10 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
println!("{:?} ==> {:?}", name, case); println!("{:?} ==> {:?}", name, case);
match case { match case {
TestCase::Test(ref bin, ref val) => { TestCase::Test(ref bin, ref val) => {
assert_eq!(&decode_all(&PackedWriter::encode_iovalue(val)?[..])?, &[val.clone()]); assert_eq!(
&decode_all(&PackedWriter::encode_iovalue(val)?[..])?,
&[val.clone()]
);
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]); assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
assert_eq!(&PackedWriter::encode_iovalue(val)?, bin); assert_eq!(&PackedWriter::encode_iovalue(val)?, bin);
} }
@ -122,11 +136,17 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
// order of keys in encoded dictionaries follows // order of keys in encoded dictionaries follows
// Preserves canonical order. // Preserves canonical order.
assert_eq!(&PackedWriter::encode_iovalue(val)?, bin); assert_eq!(&PackedWriter::encode_iovalue(val)?, bin);
assert_eq!(&decode_all(&PackedWriter::encode_iovalue(val)?[..])?, &[val.clone()]); assert_eq!(
&decode_all(&PackedWriter::encode_iovalue(val)?[..])?,
&[val.clone()]
);
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]); assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
} }
TestCase::DecodeTest(ref bin, ref val) => { TestCase::DecodeTest(ref bin, ref val) => {
assert_eq!(&decode_all(&PackedWriter::encode_iovalue(val)?[..])?, &[val.clone()]); assert_eq!(
&decode_all(&PackedWriter::encode_iovalue(val)?[..])?,
&[val.clone()]
);
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]); assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
} }
TestCase::ParseError(_) => (), TestCase::ParseError(_) => (),
@ -135,22 +155,33 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
TestCase::DecodeError(ref bin) => { TestCase::DecodeError(ref bin) => {
match decode_all(&bin[..]) { match decode_all(&bin[..]) {
Ok(_) => panic!("Unexpected success"), Ok(_) => panic!("Unexpected success"),
Err(e) => if is_syntax_io_error(&e) { Err(e) => {
// all is OK if is_syntax_io_error(&e) {
} else { // all is OK
panic!("Unexpected error {:?}", e) } else {
panic!("Unexpected error {:?}", e)
}
} }
} }
} }
TestCase::DecodeShort(ref bin) => { TestCase::DecodeShort(ref bin) => {
assert!(if let Err(e) = BytesBinarySource::new(bin).packed_iovalues().configured(true).next().unwrap() { assert!(if let Err(e) = BytesBinarySource::new(bin)
.packed_iovalues()
.configured(true)
.next()
.unwrap()
{
is_eof_io_error(&e) is_eof_io_error(&e)
} else { } else {
false false
}) })
} }
TestCase::DecodeEOF(ref bin) => { TestCase::DecodeEOF(ref bin) => {
assert!(BytesBinarySource::new(bin).packed_iovalues().configured(true).next().is_none()); assert!(BytesBinarySource::new(bin)
.packed_iovalues()
.configured(true)
.next()
.is_none());
} }
} }
} }