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)
}
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))
}

View File

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

View File

@ -1,7 +1,7 @@
use crate::CompilationError;
use crate::context::Env;
use crate::schemas::path;
use crate::step::Node;
use crate::CompilationError;
use preserves::value::BinarySource;
use preserves::value::BytesBinarySource;
@ -49,7 +49,10 @@ pub fn parse_predicate(env: &Env, tokens: &[IOValue]) -> Result<path::Predicate,
match binop {
None => parse_non_binop(env, &pieces[0]),
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 {
Binop::Union => path::Predicate::Or { 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();
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> {
let defpath = token.value().to_symbol().map_err(|_| CompilationError::InvalidStep)?;
fn parse_schema_definition_name(
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 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) {
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() {
return Ok(None);
}
@ -88,9 +109,15 @@ fn parse_step<'a>(env: &Env, tokens: &'a [IOValue]) -> Result<Option<(path::Step
let remainder = &tokens[1..];
if tokens[0].value().is_sequence() {
return Ok(Some((path::Step::Filter(Box::new(path::Filter::Test {
pred: Box::new(parse_predicate(env, tokens[0].value().as_sequence().unwrap())?),
})), remainder)));
return Ok(Some((
path::Step::Filter(Box::new(path::Filter::Test {
pred: Box::new(parse_predicate(
env,
tokens[0].value().as_sequence().unwrap(),
)?),
})),
remainder,
)));
}
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() {
None => return Err(CompilationError::InvalidStep),
Some(t) => match t.as_str() {
"count" => return Ok(Some((
path::Step::Function(Box::new(path::Function {
selector: parse_selector(env, r.fields())?,
})),
remainder
))),
"count" => {
return Ok(Some((
path::Step::Function(Box::new(path::Function {
selector: parse_selector(env, r.fields())?,
})),
remainder,
)))
}
_ => return Err(CompilationError::InvalidStep),
}
}
},
},
}
match tokens[0].value().as_symbol() {
None => return Err(CompilationError::InvalidStep),
Some(t) => match t.as_str() {
"/" => Ok(Some((path::Step::Axis(Box::new(path::Axis::Values)), remainder))),
"//" => Ok(Some((path::Step::Axis(Box::new(path::Axis::Descendants)), remainder))),
"/" => Ok(Some((
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)?;
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))),
".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))),
".^" => Ok(Some((
path::Step::Axis(Box::new(path::Axis::Label)),
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 (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 (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),
"ne" | "!=" => parse_comparison(remainder, path::Comparison::Ne),
"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),
"re" | "=r" => {
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)?;
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)?;
Ok(Some((path::Step::Filter(Box::new(path::Filter::Test {
pred: Box::new(path::Predicate::Selector(Box::new(path::Selector(vec![
path::Step::Axis(Box::new(path::Axis::Label)),
path::Step::Filter(Box::new(path::Filter::Compare {
op: Box::new(path::Comparison::Eq),
literal,
})),
])))),
})), remainder)))
Ok(Some((
path::Step::Filter(Box::new(path::Filter::Test {
pred: Box::new(path::Predicate::Selector(Box::new(path::Selector(vec![
path::Step::Axis(Box::new(path::Axis::Label)),
path::Step::Filter(Box::new(path::Filter::Compare {
op: Box::new(path::Comparison::Eq),
literal,
})),
])))),
})),
remainder,
)))
}
"~real" => Ok(Some((path::Step::Filter(Box::new(path::Filter::Real)), remainder))),
"~int" => Ok(Some((path::Step::Filter(Box::new(path::Filter::Int)), remainder))),
"~real" => Ok(Some((
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))),
"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))),
"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))),
"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))),
"dict" => Ok(Some((path::Step::from(path::ValueKind::Dictionary), remainder))),
"embedded" => Ok(Some((path::Step::from(path::ValueKind::Embedded), remainder))),
"dict" => Ok(Some((
path::Step::from(path::ValueKind::Dictionary),
remainder,
))),
"embedded" => Ok(Some((
path::Step::from(path::ValueKind::Embedded),
remainder,
))),
_ => Err(CompilationError::InvalidStep),
}
},
}
}
impl From<path::ValueKind> for path::Step {
fn from(k: path::ValueKind) -> Self {
path::Step::Filter(Box::new(path::Filter::Kind {
kind: Box::new(k),
}))
path::Step::Filter(Box::new(path::Filter::Kind { kind: Box::new(k) }))
}
}
@ -200,18 +294,24 @@ fn parse_comparison(
op: path::Comparison,
) -> Result<Option<(path::Step, &[IOValue])>, CompilationError> {
let (literal, remainder) = pop_step_arg(tokens)?;
Ok(Some((path::Step::Filter(Box::new(path::Filter::Compare {
op: Box::new(op),
literal,
})), remainder)))
Ok(Some((
path::Step::Filter(Box::new(path::Filter::Compare {
op: Box::new(op),
literal,
})),
remainder,
)))
}
impl path::Selector {
pub fn from_str(env: &Env, s: &str) -> Result<Self, CompilationError> {
parse_selector(env, &(BytesBinarySource::new(s.as_bytes())
.text_iovalues()
.configured(false)
.collect::<Result<Vec<_>, _>>()?))
parse_selector(
env,
&(BytesBinarySource::new(s.as_bytes())
.text_iovalues()
.configured(false)
.collect::<Result<Vec<_>, _>>()?),
)
}
}

View File

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

View File

@ -1,15 +1,15 @@
// Selectors operate on IOValues because the AST includes keys of IOValue type.
// If we could make Schemas produce generics...
use crate::CompilationError;
use crate::context::Context;
use crate::predicate::CompiledPredicate;
use crate::predicate::Predicate;
use crate::schemas::path;
use crate::CompilationError;
use num::bigint::BigInt;
use num::traits::cast::ToPrimitive;
use num::traits::cast::FromPrimitive;
use num::traits::cast::ToPrimitive;
use preserves::value::AtomClass;
use preserves::value::CompoundClass;
@ -161,7 +161,10 @@ impl StepMaker for path::Step {
impl StepMaker for path::Axis {
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 {
fn accept(&mut self, ctxt: &mut Context, value: &IOValue) {
ctxt.with_path_step(value, |ctxt| match &self.axis {
path::Axis::Values =>
path::Axis::Values => {
for c in value.value().children() {
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() {
Value::String(s) | Value::Symbol(s) =>
step_index(ctxt, s.chars(), &key, |c| IOValue::new(String::from(c)), &mut self.step),
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) =>
Value::String(s) | Value::Symbol(s) => step_index(
ctxt,
s.chars(),
&key,
|c| IOValue::new(String::from(c)),
&mut self.step,
),
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) {
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() {
Value::String(s) | Value::Symbol(s) =>
step_keys(ctxt, s.len(), &mut self.step),
Value::String(s) | Value::Symbol(s) => step_keys(ctxt, s.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::Sequence(vs) => step_keys(ctxt, vs.len(), &mut self.step),
Value::Dictionary(d) =>
Value::Dictionary(d) => {
for k in d.keys() {
self.step.accept(ctxt, k)
},
}
}
_ => (),
},
path::Axis::Length => match value.value() {
Value::String(s) | Value::Symbol(s) =>
self.step.accept(ctxt, &IOValue::new(s.len())),
Value::String(s) | Value::Symbol(s) => {
self.step.accept(ctxt, &IOValue::new(s.len()))
}
Value::ByteString(bs) => self.step.accept(ctxt, &IOValue::new(bs.len())),
Value::Record(r) => self.step.accept(ctxt, &IOValue::new(r.arity())),
Value::Sequence(vs) => self.step.accept(ctxt, &IOValue::new(vs.len())),
Value::Dictionary(d) => self.step.accept(ctxt, &IOValue::new(d.len())),
_ => self.step.accept(ctxt, &IOValue::new(0)),
},
path::Axis::Annotations =>
path::Axis::Annotations => {
for c in value.annotations().slice() {
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 } => {
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)
}
}
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)
}
}
@ -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) {
for i in 0 .. count {
for i in 0..count {
step.accept(ctxt, &IOValue::new(i))
}
}
@ -272,8 +292,14 @@ impl StepMaker for path::Filter {
literal: literal.clone(),
step,
})),
path::Filter::Regex { regex } => Ok(Node::new(RegexStep { regex: regex::Regex::new(regex)?, step })),
path::Filter::Test { pred } => Ok(Node::new(TestStep { pred: (&**pred).compile()?, step })),
path::Filter::Regex { regex } => Ok(Node::new(RegexStep {
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::Int => Ok(Node::new(IntStep { step })),
path::Filter::Kind { kind } => Ok(Node::new(KindStep {
@ -317,10 +343,12 @@ impl Step for CompareStep {
impl Step for RegexStep {
fn accept(&mut self, ctxt: &mut Context, value: &IOValue) {
match value.value() {
Value::String(s) | Value::Symbol(s) =>
if self.regex.is_match(s) { self.step.accept(ctxt, value) },
_ =>
(),
Value::String(s) | Value::Symbol(s) => {
if self.regex.is_match(s) {
self.step.accept(ctxt, value)
}
}
_ => (),
}
}
@ -340,9 +368,11 @@ impl Step for TestStep {
impl Step for RealStep {
fn accept(&mut self, ctxt: &mut Context, value: &IOValue) {
match value.value() {
Value::SignedInteger(i) => if let Some(r) = BigInt::from(i).to_f64() {
self.step.accept(ctxt, &IOValue::new(r))
},
Value::SignedInteger(i) => {
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::Double(_) => self.step.accept(ctxt, value),
_ => (),
@ -356,12 +386,16 @@ impl Step for IntStep {
fn accept(&mut self, ctxt: &mut Context, value: &IOValue) {
match value.value() {
Value::SignedInteger(_) => self.step.accept(ctxt, value),
Value::Float(f) => 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::Float(f) => {
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))
}
}
_ => (),
}
}
@ -371,7 +405,9 @@ impl Step for IntStep {
impl VecCollector {
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())
}
fn finish(&mut self) {
}
fn finish(&mut self) {}
fn reset(&mut self) -> Vec<IOValue> {
std::mem::take(&mut self.accumulator)
@ -399,11 +434,14 @@ impl Step for BoolCollector {
self.seen_value = true
}
fn finish(&mut self) {
}
fn finish(&mut self) {}
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;
result
}
@ -424,7 +462,11 @@ impl path::Selector {
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))
}
}
@ -432,7 +474,10 @@ impl path::Selector {
impl StepMaker for path::Function {
fn connect(&self, step: Node) -> Result<Node, CompilationError> {
// 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
}
fn finish(&mut self) {
}
fn finish(&mut self) {}
fn reset(&mut self) -> Vec<IOValue> {
let result = vec![IOValue::new(self.count)];

View File

@ -3,7 +3,7 @@ use std::io::ErrorKind;
use std::path::PathBuf;
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)]
struct CommandLine {
@ -35,8 +35,10 @@ fn main() -> Result<(), Error> {
let (modulepath_str, target) = {
let pieces: Vec<&str> = alias.split('=').collect();
if pieces.len() != 2 {
return Err(Error::new(ErrorKind::InvalidData,
format!("Invalid module alias: {:?}", alias)));
return Err(Error::new(
ErrorKind::InvalidData,
format!("Invalid module alias: {:?}", alias),
));
}
(pieces[0], pieces[1])
};
@ -49,6 +51,7 @@ fn main() -> Result<(), Error> {
config.rustfmt_skip = args.rustfmt_skip;
config.load_schemas_and_bundles(
&expand_inputs(&args.input_glob)?,
&expand_inputs(&args.xref)?)?;
&expand_inputs(&args.xref)?,
)?;
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::syntax::block::constructors::*;
use crate::syntax::block::escape_string;
use crate::syntax::block::Item;
use crate::*;
use convert_case::{Case, Casing};
@ -13,10 +13,10 @@ use preserves::value::Map;
use preserves::value::NestedValue;
use preserves::value::Value;
use super::CompilerConfig;
use super::names;
use super::types;
use super::types::Purpose;
use super::CompilerConfig;
pub struct BundleContext<'b> {
pub config: &'b CompilerConfig,
@ -69,9 +69,7 @@ lazy_static! {
}
impl<'b> BundleContext<'b> {
pub fn new(
config: &'b CompilerConfig,
) -> Self {
pub fn new(config: &'b CompilerConfig) -> Self {
BundleContext {
config,
types: config.build_type_cache(),
@ -84,13 +82,18 @@ impl<'b> BundleContext<'b> {
}
pub fn lookup_definition(&self, r: &Ref) -> Option<(&Definition, Purpose)> {
self.config.bundle.get(&r.module.0).and_then(
|s| s.0.definitions.0.get(&r.name).map(|d| (d, s.1)))
self.config
.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> {
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);
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 next_id = match v.value() {
Value::Boolean(b) => prefix + "_" + &b.to_string(),
Value::Symbol(s) => if ID_RE.is_match(&s) { prefix + "_" + s } else { prefix },
Value::String(s) => if ID_RE.is_match(&s) { prefix + "_" + s } else { prefix },
Value::Symbol(s) => {
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(),
_ => prefix
_ => prefix,
};
let next_id = next_id.to_case(Case::UpperSnake);
format!("&<_L as Into<&'a {}>>::into(_ctxt).{}",
self.language_type(),
self.literals.entry(v.clone()).or_insert(next_id))
format!(
"&<_L as Into<&'a {}>>::into(_ctxt).{}",
self.language_type(),
self.literals.entry(v.clone()).or_insert(next_id)
)
}
pub fn generate_module<F: FnOnce(&mut ModuleContext)>(
@ -132,9 +149,11 @@ impl<'b> BundleContext<'b> {
}
pub fn language_type_base(&self) -> String {
format!("{}::{}",
self.config.fully_qualified_module_prefix.clone(),
self.language_struct_name())
format!(
"{}::{}",
self.config.fully_qualified_module_prefix.clone(),
self.language_struct_name()
)
}
pub fn language_type(&self) -> String {
@ -175,38 +194,56 @@ impl<'m, 'b> ModuleContext<'m, 'b> {
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));
self.functiondefs.push(i)
}
pub fn render_ref(&self, r: &Ref, style: RefRenderStyle) -> Item {
let base = match self.bundle.config.external_modules.get(&r.module.0) {
None =>
None => {
if r.module.0.is_empty() {
item(names::render_constructor(&r.name))
} else {
let mut items = Vec::new();
items.push(item(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(
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)));
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);
match style {
RefRenderStyle::Bare =>
base,
RefRenderStyle::Qualified =>
if q { item(seq![base, anglebrackets![self.any_type()]]) } else { base },
RefRenderStyle::Bare => base,
RefRenderStyle::Qualified => {
if q {
item(seq![base, anglebrackets![self.any_type()]])
} else {
base
}
}
}
}
pub fn ref_has_embedded(&self, r: &Ref) -> bool {
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?
}
@ -215,9 +252,15 @@ impl<'m, 'b> ModuleContext<'m, 'b> {
lts.insert(self.bundle.language_type());
item(anglebrackets![
"'a",
seq!["_L: Copy",
seq(lts.into_iter().map(|t| item(seq![" + Into<&'a ", t, ">"])).collect())],
seq![self.any_type(), ": preserves::value::NestedValue + 'a"]])
seq![
"_L: Copy",
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> {
@ -243,11 +286,13 @@ impl<'a, 'm, 'b> FunctionContext<'a, 'm, 'b> {
field_name,
ty,
source_expr: match self.capture_mode {
CaptureMode::Definite =>
CaptureMode::Definite => source_expr,
CaptureMode::Indefinite(_) => format!(
"{}.ok_or_else(|| {:?})?",
source_expr,
CaptureMode::Indefinite(_) =>
format!("{}.ok_or_else(|| {:?})?", source_expr, self.conformance_err_code()),
}
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) {
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) {
@ -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> {
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);
match std::mem::replace(&mut self.capture_mode, saved_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 {
return item(seq!["_support::ParseError::conformance_error", parens![
escape_string(&self.fully_qualified_error_context())]]);
return item(seq![
"_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>,
R,
Ks: FnOnce(&mut Self, Option<E>) -> R,
Kf: FnOnce() -> R
Kf: FnOnce() -> R,
>(
&mut self,
r: &Ref,

View File

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

View File

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

View File

@ -1,9 +1,9 @@
use crate::*;
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::escape_bytes;
use crate::syntax::block::escape_string;
use crate::syntax::block::Item;
use crate::*;
use preserves::value::AtomClass;
use preserves::value::CompoundClass;
@ -22,7 +22,12 @@ use super::types::*;
pub struct 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 {
gen_definition_reader(module_ctxt, definition_name, definition)
}
@ -56,7 +61,11 @@ impl BoundaryTracker {
) -> Self {
let tracker_name = ctxt.gentempname();
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 {
tracker_name,
item_expr,
@ -64,93 +73,151 @@ impl BoundaryTracker {
}
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(), ")?;"]));
}
fn emit_loop(&self, body: &mut Vec<Item>, inner: Vec<Item>) {
body.push(item(seq![
"while !r.close_compound", parens![
"while !r.close_compound",
parens![
seq!["&mut ", self.tracker_name.clone()],
seq!["&", self.item_expr]], "? ",
codeblock(inner)]))
seq!["&", self.item_expr]
],
"? ",
codeblock(inner)
]))
}
}
pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) {
let ty = definition_type(&m.module_path, Purpose::Codegen, n, d);
m.define_function(
n,
|mut ctxt| {
let mut body = vec![];
m.define_function(n, |mut ctxt| {
let mut body = vec![];
match d {
Definition::Or { pattern_0, pattern_1, pattern_n } => {
let mut ps = vec![&**pattern_0, &**pattern_1];
ps.extend(pattern_n);
ctxt.define_atom(&mut body, "_mark", item("r.mark()?"));
for NamedAlternative { variant_label: name, pattern: pat } in ps {
let fname = seq!["read_", 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_reader(&mut ctxt, pat, 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(), anglebrackets![
"'de",
seq![ctxt.m.any_type(), ": preserves::value::NestedValue"],
seq!["R: _support::Reader<'de, ", ctxt.m.any_type(), ">"]],
"(r: &mut R) -> ",
"std::result::Result<",
names::render_constructor(n), ty.generic_arg(ctxt.m),
", _support::ParseError> ",
codeblock(body)])
});
body.push(item(seq![
"match ", fname, "(r) { ",
"Err(e) if e.is_conformance_error() => r.restore(&_mark)?, ",
"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);
match d {
Definition::Or {
pattern_0,
pattern_1,
pattern_n,
} => {
let mut ps = vec![&**pattern_0, &**pattern_1];
ps.extend(pattern_n);
ctxt.define_atom(&mut body, "_mark", item("r.mark()?"));
for NamedAlternative {
variant_label: name,
pattern: pat,
} in ps
{
let fname = seq![
"read_",
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_reader(&mut ctxt, pat, 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(),
anglebrackets![
"'de",
seq![ctxt.m.any_type(), ": preserves::value::NestedValue"],
seq!["R: _support::Reader<'de, ", ctxt.m.any_type(), ">"]
],
"(r: &mut R) -> ",
"std::result::Result<",
names::render_constructor(n),
ty.generic_arg(ctxt.m),
", _support::ParseError> ",
codeblock(body)
])
});
body.push(item(seq![
"match ",
fname,
"(r) { ",
"Err(e) if e.is_conformance_error() => r.restore(&_mark)?, ",
"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![
"impl", anglebrackets![seq![ctxt.m.any_type(), ": preserves::value::NestedValue"]],
" _support::Deserialize", anglebrackets![ctxt.m.any_type()], " for ",
names::render_constructor(n), ty.generic_arg(ctxt.m), " ", 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)]]])
});
item(seq![
"impl",
anglebrackets![seq![ctxt.m.any_type(), ": preserves::value::NestedValue"]],
" _support::Deserialize",
anglebrackets![ctxt.m.any_type()],
" for ",
names::render_constructor(n),
ty.generic_arg(ctxt.m),
" ",
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(
@ -162,30 +229,42 @@ fn construct(
body: &mut Vec<Item>,
) {
match ty {
TSimple::Field(TField::Unit) =>
body.push(item(seq!["Ok(", ctorname, ")"])),
TSimple::Field(fieldty) =>
body.push(item(seq!["Ok(", ctorname, parens![store_wrap(is_struct, fieldty, dest.unwrap())], ")"])),
TSimple::Record(_) =>
body.push(item(seq!["Ok(", ctorname, " ", braces(
ctxt.captures.iter().map(
|c| item(seq![c.field_name.clone(), ": ", store_wrap(is_struct, &c.ty, &c.source_expr)])).collect()),
")"])),
TSimple::Field(TField::Unit) => body.push(item(seq!["Ok(", ctorname, ")"])),
TSimple::Field(fieldty) => body.push(item(seq![
"Ok(",
ctorname,
parens![store_wrap(is_struct, fieldty, dest.unwrap())],
")"
])),
TSimple::Record(_) => body.push(item(seq![
"Ok(",
ctorname,
" ",
braces(
ctxt.captures
.iter()
.map(|c| item(seq![
c.field_name.clone(),
": ",
store_wrap(is_struct, &c.ty, &c.source_expr)
]))
.collect()
),
")"
])),
}
}
fn store_wrap(is_struct: bool, ty: &TField, expr: &str) -> String {
match ty {
TField::Unit
| TField::Array(_)
| TField::Set(_)
| TField::Map(_, _) => expr.to_owned(),
TField::Ref(_) =>
TField::Unit | TField::Array(_) | TField::Set(_) | TField::Map(_, _) => expr.to_owned(),
TField::Ref(_) => {
if is_struct {
expr.to_owned()
} else {
format!("std::boxed::Box::new({})", expr)
},
}
}
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)) {
match current_key.cmp(&Some(k.clone())) {
std::cmp::Ordering::Equal => (),
std::cmp::Ordering::Less |
std::cmp::Ordering::Greater => {
std::cmp::Ordering::Less | std::cmp::Ordering::Greater => {
if let Some(k) = current_key {
result.push((k, std::mem::take(&mut buf)));
}
@ -227,10 +305,12 @@ fn read_expected_literal_seqs(
body: &mut Vec<Item>,
possibilities: LiteralSeqCases,
) {
let grouped = group_by(possibilities, |(vs, _f)| if vs.is_empty() {
None
} else {
Some(vs[0].clone())
let grouped = group_by(possibilities, |(vs, _f)| {
if vs.is_empty() {
None
} else {
Some(vs[0].clone())
}
});
let mut cases = Vec::new();
let mut nested: LiteralCases = Vec::new();
@ -239,16 +319,25 @@ fn read_expected_literal_seqs(
None => {
let mut inner = Vec::new();
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) => {
let tails = group.into_iter().map(|(mut vs, f)| {
vs.remove(0);
(vs, f)
}).collect();
nested.push((h, Box::new(|ctxt: &mut FunctionContext, b: &'_ mut Vec<Item>| {
read_expected_literal_seqs(ctxt, b, tails)
})));
let tails = group
.into_iter()
.map(|(mut vs, f)| {
vs.remove(0);
(vs, f)
})
.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 => {
ctxt.define_atom(body, &dest, item("r.demand_next(true)?"));
dest
},
}
SimplePattern::Atom { atom_kind: k } => {
let reader = match &**k {
AtomKind::Boolean => "r.next_boolean()?",
@ -361,54 +450,74 @@ fn simple_pattern_reader(
};
ctxt.define_atom(body, &dest, item(reader.to_owned()));
dest
},
}
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
},
}
SimplePattern::Lit { value } => {
let f = Box::new(|_ctxt: &mut FunctionContext, _: &'_ mut Vec<Item>| ());
read_expected_literals(ctxt, body, vec![(value.clone(), f)]);
ctxt.define_atom(body, &dest, item("()"));
dest
},
}
SimplePattern::Seqof { pattern } => {
let compound_dest = ctxt.gentempname();
ctxt.with_definite_mode(|ctxt| {
let boundary_tracker = BoundaryTracker::unwrap(
ctxt, body, "r.open_sequence()?;", boundary_tracker);
let boundary_tracker =
BoundaryTracker::unwrap(ctxt, body, "r.open_sequence()?;", boundary_tracker);
let mut inner = Vec::new();
boundary_tracker.emit_boundary(&mut inner);
let item_dest = simple_pattern_reader(ctxt, pattern, None, &mut inner);
inner.push(item(seq![compound_dest.to_owned(), ".push(",
store_wrap(true, &field_type(pattern), &item_dest), ");"]));
inner.push(item(seq![
compound_dest.to_owned(),
".push(",
store_wrap(true, &field_type(pattern), &item_dest),
");"
]));
ctxt.declare_compound(body, &compound_dest, item("std::vec::Vec::new()"));
boundary_tracker.emit_loop(body, inner);
});
ctxt.define_atom(body, &dest, item(compound_dest));
dest
},
}
SimplePattern::Setof { pattern } => {
let compound_dest = ctxt.gentempname();
ctxt.with_definite_mode(|ctxt| {
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();
boundary_tracker.emit_boundary(&mut inner);
let item_dest = simple_pattern_reader(ctxt, pattern, None, &mut inner);
inner.push(item(seq![compound_dest.to_owned(), ".insert(",
store_wrap(true, &field_type(pattern), &item_dest), ");"]));
inner.push(item(seq![
compound_dest.to_owned(),
".insert(",
store_wrap(true, &field_type(pattern), &item_dest),
");"
]));
ctxt.declare_compound(body, &compound_dest, item("preserves::value::Set::new()"));
boundary_tracker.emit_loop(body, inner);
});
ctxt.define_atom(body, &dest, item(compound_dest));
dest
},
}
SimplePattern::Dictof { key, value } => {
let compound_dest = ctxt.gentempname();
ctxt.with_definite_mode(|ctxt| {
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();
boundary_tracker.emit_boundary(&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);
let value_dest = simple_pattern_reader(ctxt, value, None, &mut inner);
inner.push(item(seq![
compound_dest.to_owned(), ".insert(",
store_wrap(true, &field_type(key), &key_dest), ", ",
store_wrap(true, &field_type(value), &value_dest), ");"]));
compound_dest.to_owned(),
".insert(",
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()"));
boundary_tracker.item_expr = "_support::B::Item::DictionaryKey";
boundary_tracker.emit_loop(body, inner);
});
ctxt.define_atom(body, &dest, item(compound_dest));
dest
},
}
SimplePattern::Ref(r) => {
let tf = name![ctxt.m.render_ref(&**r, RefRenderStyle::Bare), "deserialize"];
ctxt.define_atom(body, &dest, item(seq![tf, "(r)?"]));
dest
},
}
}
}
@ -443,9 +556,9 @@ fn named_pattern_reader(
match p {
NamedPattern::Anonymous(p) => {
pattern_reader(ctxt, p, boundary_tracker, body);
},
}
NamedPattern::Named(b) => {
let Binding { name, pattern} = &**b;
let Binding { name, pattern } = &**b;
let dest = simple_pattern_reader(ctxt, pattern, boundary_tracker, body);
let capture_ty = field_type(pattern);
ctxt.capture(names::render_fieldname(name), capture_ty, dest);
@ -460,41 +573,61 @@ fn pattern_reader(
body: &mut Vec<Item>,
) -> Option<String> {
match p {
Pattern::SimplePattern(s) =>
Some(simple_pattern_reader(ctxt, s, boundary_tracker, body)),
Pattern::SimplePattern(s) => Some(simple_pattern_reader(ctxt, s, boundary_tracker, body)),
Pattern::CompoundPattern(c) => {
match &**c {
CompoundPattern::Rec { label, fields } => {
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.item_expr = "_support::B::Item::RecordField";
named_pattern_reader(ctxt, &**label, None, body);
named_pattern_reader(ctxt, &**fields, Some(&boundary_tracker), body);
},
}
CompoundPattern::Tuple { patterns } => {
let boundary_tracker = BoundaryTracker::unwrap(
ctxt, body, "r.open_sequence()?;", boundary_tracker);
ctxt,
body,
"r.open_sequence()?;",
boundary_tracker,
);
for p in patterns {
boundary_tracker.emit_boundary(body);
named_pattern_reader(ctxt, p, None, body);
}
body.push(item(seq!["r.ensure_complete", parens![
boundary_tracker.tracker_name.clone(),
seq!["&", boundary_tracker.item_expr]], "?;"]));
},
body.push(item(seq![
"r.ensure_complete",
parens![
boundary_tracker.tracker_name.clone(),
seq!["&", boundary_tracker.item_expr]
],
"?;"
]));
}
CompoundPattern::TuplePrefix { fixed, variable } => {
let boundary_tracker = BoundaryTracker::unwrap(
ctxt, body, "r.open_sequence()?;", boundary_tracker);
ctxt,
body,
"r.open_sequence()?;",
boundary_tracker,
);
for p in fixed {
boundary_tracker.emit_boundary(body);
named_pattern_reader(ctxt, p, None, body);
}
named_pattern_reader(ctxt, &promote(variable), Some(&boundary_tracker), body);
},
}
CompoundPattern::Dict { entries } => {
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();
boundary_tracker.emit_boundary(&mut inner);
let mut val_boundary_tracker = boundary_tracker.clone();
@ -516,6 +649,6 @@ fn pattern_reader(
}
}
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::syntax::block::constructors::*;
use crate::syntax::block::{Emittable, Item};
use crate::*;
use preserves::value::Set;
@ -26,8 +26,8 @@ pub struct TDefinition {
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum TDefinitionBody {
Union(Vec<(String, TSimple)>),
Simple(TSimple),
Union(Vec<(String, TSimple)>),
Simple(TSimple),
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
@ -57,11 +57,18 @@ pub struct TypePlugin;
impl compiler::Plugin for TypePlugin {
fn generate_module(&self, m: &mut ModuleContext) {
if let EmbeddedTypeName::Ref(r) = &m.schema.embedded_type {
m.define_type(item(vertical(false, seq![
seq!["pub type _Dom = ", m.render_ref(&*r, RefRenderStyle::Bare), ";"],
seq!["pub type _Ptr = std::sync::Arc<_Dom>;"],
seq!["pub type _Any = preserves::value::ArcValue<_Ptr>;"]
])));
m.define_type(item(vertical(
false,
seq![
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);
m.define_type(item(ty.render(m, n)));
m.define_type(item(seq![
"impl", ty.generic_decl(m), " preserves::value::Domain for ",
names::render_constructor(n), ty.generic_arg(m), " {}"]));
"impl",
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 {
purpose,
self_ref: Ref { module: module.clone(), name: n.to_owned() },
self_ref: Ref {
module: module.clone(),
name: n.to_owned(),
},
body: match d {
Definition::Or { pattern_0, pattern_1, pattern_n } =>
TDefinitionBody::Union(or_definition_type(pattern_0, pattern_1, pattern_n)),
Definition::And { pattern_0, pattern_1, pattern_n } =>
TDefinitionBody::Simple(and_definition_type(pattern_0, pattern_1, pattern_n)),
Definition::Pattern(p) =>
TDefinitionBody::Simple(pattern_type(p)),
}
Definition::Or {
pattern_0,
pattern_1,
pattern_n,
} => TDefinitionBody::Union(or_definition_type(pattern_0, pattern_1, pattern_n)),
Definition::And {
pattern_0,
pattern_1,
pattern_n,
} => TDefinitionBody::Simple(and_definition_type(pattern_0, pattern_1, pattern_n)),
Definition::Pattern(p) => TDefinitionBody::Simple(pattern_type(p)),
},
}
}
@ -117,10 +142,10 @@ pub fn and_definition_type(
pub fn pattern_type(p: &Pattern) -> TSimple {
match p {
Pattern::SimplePattern(p) =>
TSimple::Field(field_type(p)),
Pattern::CompoundPattern(_) =>
record_type(&vec![&NamedPattern::Anonymous(Box::new(p.clone()))]),
Pattern::SimplePattern(p) => TSimple::Field(field_type(p)),
Pattern::CompoundPattern(_) => {
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() {
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;
fs.push((name.to_owned(), field_type(pattern)));
fs
},
}
NamedPattern::Anonymous(p) => match &**p {
Pattern::SimplePattern(_) =>
fs,
Pattern::SimplePattern(_) => fs,
Pattern::CompoundPattern(c) => match &**c {
CompoundPattern::Rec { label, fields } =>
gather_field(&*fields, gather_field(&*label, fs)),
CompoundPattern::Tuple { patterns } =>
gather_fields(&patterns.iter().collect(), fs),
CompoundPattern::TuplePrefix { fixed, variable } =>
gather_field(&promote(&**variable), gather_fields(&fixed.iter().collect(), fs)),
CompoundPattern::Rec { label, fields } => {
gather_field(&*fields, gather_field(&*label, fs))
}
CompoundPattern::Tuple { patterns } => {
gather_fields(&patterns.iter().collect(), fs)
}
CompoundPattern::TuplePrefix { fixed, variable } => gather_field(
&promote(&**variable),
gather_fields(&fixed.iter().collect(), fs),
),
CompoundPattern::Dict { entries } => {
for (_k, p) in &entries.0 {
fs = gather_field(&promote(&p), fs);
}
fs
}
}
}
},
},
}
}
pub fn promote(p: &NamedSimplePattern) -> NamedPattern {
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()),
}
}
@ -179,22 +211,24 @@ pub fn promote(p: &NamedSimplePattern) -> NamedPattern {
pub fn field_type(p: &SimplePattern) -> TField {
match p {
SimplePattern::Any => TField::Any,
SimplePattern::Atom { atom_kind: k } =>
match **k {
AtomKind::Boolean => TField::Base("bool".to_owned()),
AtomKind::Float => TField::Base("preserves::value::Float".to_owned()),
AtomKind::Double => TField::Base("preserves::value::Double".to_owned()),
AtomKind::SignedInteger => 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::Symbol => TField::Base("std::string::String".to_owned()),
},
SimplePattern::Atom { atom_kind: k } => match **k {
AtomKind::Boolean => TField::Base("bool".to_owned()),
AtomKind::Float => TField::Base("preserves::value::Float".to_owned()),
AtomKind::Double => TField::Base("preserves::value::Double".to_owned()),
AtomKind::SignedInteger => {
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::Symbol => TField::Base("std::string::String".to_owned()),
},
SimplePattern::Embedded { .. } => TField::Embedded,
SimplePattern::Lit { .. } => TField::Unit,
SimplePattern::Seqof { pattern: t } => TField::Array(Box::new(field_type(t))),
SimplePattern::Setof { pattern: t } => TField::Set(Box::new(field_type(t))),
SimplePattern::Dictof { key: k, value: v } =>
TField::Map(Box::new(field_type(k)), Box::new(field_type(v))),
SimplePattern::Dictof { key: k, value: v } => {
TField::Map(Box::new(field_type(k)), Box::new(field_type(v)))
}
SimplePattern::Ref(r) => TField::Ref((**r).clone()),
}
}
@ -209,16 +243,20 @@ impl TField {
TField::Embedded => seq![ctxt.any_type(), "::Embedded"],
TField::Array(t) => seq!["std::vec::Vec<", t.render(ctxt, false), ">"],
TField::Set(t) => seq!["preserves::value::Set<", t.render(ctxt, false), ">"],
TField::Map(k, v) => seq!["preserves::value::Map",
anglebrackets![k.render(ctxt, false),
v.render(ctxt, false)]],
TField::Ref(r) =>
TField::Map(k, v) => seq![
"preserves::value::Map",
anglebrackets![k.render(ctxt, false), v.render(ctxt, false)]
],
TField::Ref(r) => {
if box_needed {
seq!["std::boxed::Box", anglebrackets![
ctxt.render_ref(r, RefRenderStyle::Qualified)]]
seq![
"std::boxed::Box",
anglebrackets![ctxt.render_ref(r, RefRenderStyle::Qualified)]
]
} else {
seq![ctxt.render_ref(r, RefRenderStyle::Qualified)]
},
}
}
TField::Base(n) => seq![n.to_owned()],
}
}
@ -232,21 +270,26 @@ impl TField {
k.language_types(s, ts);
v.language_types(s, ts);
}
TField::Ref(r) =>
s.cycle_check(
r,
|ctxt, r| ctxt.type_for_name(r),
|s, t| match t {
Some(ty) if ty.purpose == Purpose::Codegen => ty._language_types(s, ts),
Some(_) | None => {
let xmts = &s.context.config.external_modules.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()));
}
TField::Ref(r) => s.cycle_check(
r,
|ctxt, r| ctxt.type_for_name(r),
|s, t| match t {
Some(ty) if ty.purpose == Purpose::Codegen => ty._language_types(s, ts),
Some(_) | None => {
let xmts = &s
.context
.config
.external_modules
.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::Map(k, v) => k.has_embedded(s) || v.has_embedded(s),
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(
r,
|ctxt, r| ctxt.type_for_name(r),
|s, t| t.map(|t| t._has_embedded(s)).unwrap_or(false),
|| false),
|| false,
)
}
}
}
}
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 ppub = if is_struct { "pub " } else { "" };
seq![names::render_constructor(n), ptr.to_owned(),
match self {
TSimple::Record(TRecord(fs)) => seq![" ", vertical(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],
}]
seq![
names::render_constructor(n),
ptr.to_owned(),
match self {
TSimple::Record(TRecord(fs)) => seq![
" ",
vertical(
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>) {
@ -301,8 +368,10 @@ impl TSimple {
impl TDefinition {
pub fn generic_decl(&self, ctxt: &ModuleContext) -> Item {
if self.has_embedded(ctxt.bundle) {
item(anglebrackets![
seq![ctxt.any_type(), ": preserves::value::NestedValue"]])
item(anglebrackets![seq![
ctxt.any_type(),
": preserves::value::NestedValue"
]])
} else {
item("")
}
@ -310,12 +379,14 @@ impl TDefinition {
pub fn generic_decl_with_defaults(&self, ctxt: &ModuleContext) -> Item {
if self.has_embedded(ctxt.bundle) {
item(anglebrackets![
seq![ctxt.any_type(), ": preserves::value::NestedValue = ",
match ctxt.schema.embedded_type {
EmbeddedTypeName::False => "preserves::value::IOValue",
EmbeddedTypeName::Ref(_) => "_Any",
}]])
item(anglebrackets![seq![
ctxt.any_type(),
": preserves::value::NestedValue = ",
match ctxt.schema.embedded_type {
EmbeddedTypeName::False => "preserves::value::IOValue",
EmbeddedTypeName::Ref(_) => "_Any",
}
]])
} else {
item("")
}
@ -330,17 +401,33 @@ impl TDefinition {
}
pub fn render(&self, ctxt: &ModuleContext, n: &str) -> impl Emittable {
vertical(false, seq![
"#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash)]",
match &self.body {
TDefinitionBody::Union(items) =>
seq!["pub enum ",
names::render_constructor(n), self.generic_decl_with_defaults(ctxt), " ",
vertical(false, braces(items.iter().map(
|(n, d)| item(d.render(ctxt, item(""), false, n))).collect()))],
TDefinitionBody::Simple(s) =>
seq!["pub struct ", s.render(ctxt, self.generic_decl_with_defaults(ctxt), true, n)],
}])
vertical(
false,
seq![
"#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash)]",
match &self.body {
TDefinitionBody::Union(items) => seq![
"pub enum ",
names::render_constructor(n),
self.generic_decl_with_defaults(ctxt),
" ",
vertical(
false,
braces(
items
.iter()
.map(|(n, d)| item(d.render(ctxt, item(""), false, n)))
.collect()
)
)
],
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> {
@ -355,7 +442,9 @@ impl TDefinition {
fn _language_types(&self, s: &mut WalkState, ts: &mut Set<String>) {
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),
}
}

View File

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

View File

@ -1,9 +1,9 @@
use crate::gen::schema::*;
use preserves::value::merge::merge2;
use preserves::value::Map;
use preserves::value::NestedValue;
use preserves::value::Value;
use preserves::value::merge::merge2;
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> {
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 definition = schema.and_then(|s| s.definitions.0.get(name));
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> {
fn dynamic_parse(&self, ctxt: &mut Context<V>, v: &V) -> Option<V> {
match self {
Definition::Or { pattern_0, pattern_1, pattern_n } =>
pattern_0.dynamic_parse(ctxt, v)
Definition::Or {
pattern_0,
pattern_1,
pattern_n,
} => pattern_0
.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))),
Definition::And { pattern_0, pattern_1, pattern_n } =>
pattern_0.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)))
})))
Definition::And {
pattern_0,
pattern_1,
pattern_n,
} => pattern_0
.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()),
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);
match w {
DynField::Simple(field) => r.fields_vec_mut().push(field),
DynField::Compound(fields) => if fields.len() > 0 {
r.fields_vec_mut().push(V::new(fields))
DynField::Compound(fields) => {
if fields.len() > 0 {
r.fields_vec_mut().push(V::new(fields))
}
}
}
r.finish().wrap()
@ -83,9 +96,12 @@ impl<V: NestedValue> NamedPattern<V> {
match self {
NamedPattern::Named(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 {
NamedSimplePattern::Named(b) => {
let binding = &**b;
binding.pattern.dynamic_parse(ctxt, v).map(
|w| DynField::Compound(w.to_map(Some(&binding.name))))
binding
.pattern
.dynamic_parse(ctxt, v)
.map(|w| DynField::Compound(w.to_map(Some(&binding.name))))
}
NamedSimplePattern::Anonymous(b) =>
b.dynamic_parse(ctxt, v),
NamedSimplePattern::Anonymous(b) => 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::Float => v.value().is_float().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::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())),
},
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::Seqof { pattern } =>
v.value().as_sequence()
.and_then(|vs| vs.iter().map(|v| (**pattern).dynamic_parse(ctxt, v).map(|w| w.finish()))
.collect::<Option<Vec<V>>>())
SimplePattern::Seqof { pattern } => v
.value()
.as_sequence()
.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))),
SimplePattern::Setof { pattern } =>
v.value().as_set()
.and_then(|vs| vs.iter().map(|v| (**pattern).dynamic_parse(ctxt, v).map(|w| w.finish()))
.collect::<Option<Vec<V>>>())
SimplePattern::Setof { pattern } => v
.value()
.as_set()
.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))),
SimplePattern::Dictof { key, value } =>
v.value().as_dictionary()
SimplePattern::Dictof { key, value } => v
.value()
.as_dictionary()
.and_then(|d| {
d.iter().map(|(k, v)| {
(**key).dynamic_parse(ctxt, k)
.and_then(|kw| (**value).dynamic_parse(ctxt, v)
.map(|vw| (kw.finish(), vw.finish())))
}).collect::<Option<Map<V, V>>>()
d.iter()
.map(|(k, v)| {
(**key).dynamic_parse(ctxt, k).and_then(|kw| {
(**value)
.dynamic_parse(ctxt, v)
.map(|vw| (kw.finish(), vw.finish()))
})
})
.collect::<Option<Map<V, V>>>()
})
.map(|d| DynField::Simple(V::new(d))),
SimplePattern::Ref(r) =>
ctxt.dynamic_parse(&r.module.0, &r.name, v).map(DynField::Simple),
SimplePattern::Ref(r) => ctxt
.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> {
fn dynamic_parse(&self, ctxt: &mut Context<V>, v: &V) -> Option<Map<V, V>> {
match self {
CompoundPattern::Rec { label, fields } =>
v.value().as_record(None).and_then(
|r| (**label).dynamic_parse(ctxt, r.label()).and_then(
|lw| (**fields).dynamic_parse(ctxt, &V::new(r.fields().to_vec())).and_then(
|fsw| merge(lw, fsw)))),
CompoundPattern::Tuple { patterns } =>
v.value().as_sequence().and_then(
|vs| if vs.len() == patterns.len() {
patterns.iter().zip(vs)
CompoundPattern::Rec { label, fields } => v.value().as_record(None).and_then(|r| {
(**label).dynamic_parse(ctxt, r.label()).and_then(|lw| {
(**fields)
.dynamic_parse(ctxt, &V::new(r.fields().to_vec()))
.and_then(|fsw| merge(lw, fsw))
})
}),
CompoundPattern::Tuple { patterns } => v.value().as_sequence().and_then(|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)| {
acc.and_then(|acc| p.dynamic_parse(ctxt, v).and_then(
|w| merge(acc, w)))
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)| {
acc.and_then(|acc| p.dynamic_parse(ctxt, v).and_then(
|w| merge(acc, w)))
}).and_then(|fixed_ws| {
.and_then(|fixed_ws| {
let remainder = V::new(vs[fixed.len()..].to_vec());
(**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 {
None
}),
CompoundPattern::Dict { entries } =>
v.value().as_dictionary().and_then(
|d| (**entries).0.iter().fold(Some(Map::new()), |acc, (k, p)| {
acc.and_then(|acc| d.get(k).and_then(|v| p.dynamic_parse(ctxt, v).and_then(
|w| merge(acc, w.unwrap_compound()))))
})),
}
})
}
CompoundPattern::Dict { entries } => v.value().as_dictionary().and_then(|d| {
(**entries).0.iter().fold(Some(Map::new()), |acc, (k, p)| {
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>> {
merge2(V::new(a), V::new(b))
.map(|d| d.value_owned().into_dictionary().expect("merge to yield Dictionary"))
merge2(V::new(a), V::new(b)).map(|d| {
d.value_owned()
.into_dictionary()
.expect("merge to yield Dictionary")
})
}

View File

@ -1,8 +1,8 @@
pub use lazy_static::lazy_static;
pub use preserves;
pub use preserves::value::Reader;
pub use preserves::value::boundary as B;
pub use preserves::value::Reader;
pub mod interpret;
@ -61,7 +61,7 @@ impl<L, N: NestedValue> Codec<N> for L {
pub trait Deserialize<N: NestedValue>
where
Self: Sized
Self: Sized,
{
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)
}
pub fn decode_embedded<D: Domain>(
v: &IOValue,
) -> Result<ArcValue<Arc<D>>, ParseError>
pub fn decode_embedded<D: Domain>(v: &IOValue) -> Result<ArcValue<Arc<D>>, ParseError>
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)?))))
}
pub fn encode_embedded<D: Domain>(
v: &ArcValue<Arc<D>>,
) -> IOValue
pub fn encode_embedded<D: Domain>(v: &ArcValue<Arc<D>>) -> IOValue
where
for<'a> IOValue: From<&'a D>
for<'a> IOValue: From<&'a D>,
{
v.copy_via::<_, _, std::convert::Infallible>(
&mut |d| Ok(Value::Embedded(IOValue::from(d)))).unwrap()
v.copy_via::<_, _, std::convert::Infallible>(&mut |d| Ok(Value::Embedded(IOValue::from(d))))
.unwrap()
}
#[derive(Error, Debug)]
@ -100,10 +96,10 @@ pub enum ParseError {
impl From<preserves::error::Error> for ParseError {
fn from(v: preserves::error::Error) -> Self {
match v {
preserves::error::Error::Expected(_, _) =>
ParseError::ConformanceError("preserves::error::Error::Expected"),
_ =>
ParseError::Preserves(v),
preserves::error::Error::Expected(_, _) => {
ParseError::ConformanceError("preserves::error::Error::Expected")
}
_ => ParseError::Preserves(v),
}
}
}
@ -129,6 +125,10 @@ impl ParseError {
}
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) {
for e in self.iter() {
f.write(e)
@ -159,8 +162,14 @@ impl Vertical for Sequence {
}
first = false;
e.write_on(f);
let delim = if i == 1 { self.terminator } else { self.separator };
delim.trim_end_matches(|c: char| c.is_whitespace() && c != '\n').write_on(f);
let delim = if i == 1 {
self.terminator
} else {
self.separator
};
delim
.trim_end_matches(|c: char| c.is_whitespace() && c != '\n')
.write_on(f);
i = i - 1;
}
}
@ -263,43 +272,74 @@ pub fn escape_bytes(bs: &[u8]) -> String {
//---------------------------------------------------------------------------
pub mod constructors {
use super::Sequence;
use super::Emittable;
use super::Grouping;
use super::Item;
use super::Emittable;
use super::VerticalMode;
use super::Sequence;
use super::Vertical;
use super::VerticalMode;
pub fn item<E: 'static + Emittable>(i: E) -> Item {
std::rc::Rc::new(i)
}
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 {
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 {
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 {
Grouping { sequence: commas(items), open: "(", close: ")" }
Grouping {
sequence: commas(items),
open: "(",
close: ")",
}
}
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 {
Grouping { sequence: commas(items), open: "<", close: ">" }
Grouping {
sequence: commas(items),
open: "<",
close: ">",
}
}
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 {
@ -333,12 +373,20 @@ pub mod constructors {
}
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
}
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::BytesMut;
use clap:: {ArgEnum, Command, IntoApp, Parser, value_parser};
use clap::{value_parser, ArgEnum, Command, IntoApp, Parser};
use clap_complete::{generate, Generator, Shell};
use preserves::value::IOBinarySource;
@ -21,9 +21,9 @@ use preserves::value::Writer;
use preserves::value::text::writer::CommaStyle;
use std::iter::FromIterator;
use std::io;
use std::io::Read;
use std::iter::FromIterator;
// #[derive(ArgEnum, Clone, Debug)]
// enum Encoding {
@ -90,7 +90,6 @@ struct Convert {
// #[clap(long, arg_enum, default_value = "none")]
// output_encoding: Encoding,
#[clap(long, short, arg_enum, default_value = "auto-detect")]
input_format: InputFormat,
@ -109,10 +108,10 @@ struct Convert {
#[clap(long, arg_enum, value_name = "on/off", default_value = "on")]
indent: Boolish,
#[clap(long="select", default_value="*")]
#[clap(long = "select", default_value = "*")]
select_expr: String,
#[clap(long, arg_enum, default_value="sequence")]
#[clap(long, arg_enum, default_value = "sequence")]
select_output: SelectOutput,
#[clap(long)]
@ -126,7 +125,6 @@ struct Convert {
#[clap(long, value_name = "filename")]
bundle: Vec<std::path::PathBuf>,
// #[clap(long)]
// schema: Option<String>,
}
@ -177,7 +175,7 @@ enum Subcommand {
}
#[derive(Clone, Debug, Parser)]
#[clap(name="preserves-tool")]
#[clap(name = "preserves-tool")]
#[clap(version)]
struct CommandLine {
#[clap(subcommand)]
@ -194,7 +192,7 @@ fn main() -> io::Result<()> {
Subcommand::Completions { shell } => {
let mut cmd = CommandLine::into_app();
print_completions(shell, &mut cmd);
},
}
Subcommand::Convert(c) => convert(c)?,
Subcommand::Quote(q) => quote(q)?,
})
@ -220,7 +218,7 @@ impl<R: io::Read> RollingBuffer<R> {
fn read_more(&mut self) -> io::Result<usize> {
let mut buf = [0; 8192];
let n = self.r.read(&mut buf)?;
self.buf.put(&buf[.. n]);
self.buf.put(&buf[..n]);
Ok(n)
}
@ -228,7 +226,7 @@ impl<R: io::Read> RollingBuffer<R> {
if self.rhs() == self.pos {
let _ = self.read_more()?;
}
return Ok(&self.buf[self.pos - self.discarded ..]);
return Ok(&self.buf[self.pos - self.discarded..]);
}
fn rhs(&self) -> usize {
@ -256,29 +254,41 @@ impl<R: io::Read> RollingBuffer<R> {
}
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> {
fn seek(&mut self, offset: io::SeekFrom) -> io::Result<u64> {
let new_position = match offset {
io::SeekFrom::Current(delta) => if delta >= 0 {
self.pos + delta as usize
} else {
self.pos - (-delta) as usize
},
io::SeekFrom::Current(delta) => {
if delta >= 0 {
self.pos + delta as usize
} else {
self.pos - (-delta) as usize
}
}
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,
};
if new_position > self.rhs() {
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 {
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;
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> {
let i = self.pos - self.discarded;
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 self.read_more()? == 0 {
return Ok(0);
}
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;
return Ok(n);
}
@ -337,19 +347,26 @@ impl<R: io::Read> ValueStream<R> {
let maybe_value: Option<IOValue> = if is_text {
match self.input_format {
InputFormat::AutoDetect | InputFormat::Text => (),
InputFormat::Binary => return Err(io::Error::new(
io::ErrorKind::InvalidData, "Expected binary input, saw text input")),
InputFormat::Binary => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"Expected binary input, saw text input",
))
}
}
TextReader::new(&mut self.source, ViaCodec::new(IOValueDomainCodec))
.next(self.read_annotations)?
} else {
match self.input_format {
InputFormat::AutoDetect | InputFormat::Binary => (),
InputFormat::Text => return Err(io::Error::new(
io::ErrorKind::InvalidData, "Expected text input, saw binary input")),
InputFormat::Text => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"Expected text input, saw binary input",
))
}
}
PackedReader::new(&mut self.source, IOValueDomainCodec)
.next(self.read_annotations)?
PackedReader::new(&mut self.source, IOValueDomainCodec).next(self.read_annotations)?
};
match maybe_value {
@ -383,10 +400,12 @@ fn convert(c: Convert) -> io::Result<()> {
for f in c.bundle.iter() {
env.load_bundle(f)?;
}
let select = preserves_path::Node::from_str(&env, &c.select_expr)
.map_err(|e| io::Error::new(
let select = preserves_path::Node::from_str(&env, &c.select_expr).map_err(|e| {
io::Error::new(
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 write_ann: bool = c.write_annotations.into();
let mut w: Box<dyn FnMut(&IOValue) -> io::Result<()>> = match c.output_format {
@ -418,11 +437,10 @@ fn convert(c: Convert) -> io::Result<()> {
Ok(())
})
}
OutputFormat::Unquoted =>
Box::new(|v| {
print_unquoted(v);
Ok(())
}),
OutputFormat::Unquoted => Box::new(|v| {
print_unquoted(v);
Ok(())
}),
};
while let Some(value) = vs.next() {
let value = value?;
@ -434,8 +452,16 @@ fn convert(c: Convert) -> io::Result<()> {
}
} else {
match c.select_output {
SelectOutput::Sequence => for v in matches { w(&v)?; },
SelectOutput::Set => for v in Set::from_iter(matches) { w(&v)?; },
SelectOutput::Sequence => {
for v in matches {
w(&v)?;
}
}
SelectOutput::Set => {
for v in Set::from_iter(matches) {
w(&v)?;
}
}
}
}
if let Some(limit) = c.limit {
@ -458,8 +484,7 @@ impl Quote {
fn output_one(q: &Quote, v: &IOValue) -> io::Result<()> {
match q.output_format {
OutputFormat::Binary =>
PackedWriter::new(io::stdout()).write(&mut IOValueDomainCodec, v),
OutputFormat::Binary => PackedWriter::new(io::stdout()).write(&mut IOValueDomainCodec, v),
OutputFormat::Text => {
TextWriter::new(io::stdout())
.set_escape_spaces(q.escape_spaces())
@ -480,18 +505,16 @@ fn quote(q: Quote) -> io::Result<()> {
let mut buf = Vec::new();
io::stdin().read_to_end(&mut 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<()> {
let mut r = RollingBuffer::new(io::stdin());
while let Some(chunk) = r.read_upto(delimiter, s.include_terminator)? {
quote_chunk(q, String::from_utf8(chunk).map_err(
|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8"))?)?
quote_chunk(
q,
String::from_utf8(chunk)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8"))?,
)?
}
Ok(())
}

View File

@ -1,6 +1,8 @@
use criterion::{criterion_group, criterion_main, Criterion};
use preserves::de;
use preserves::ser;
use preserves::value;
use preserves::value::packed::annotated_iovalue_from_bytes;
use preserves::value::BinarySource;
use preserves::value::BytesBinarySource;
use preserves::value::IOBinarySource;
@ -8,12 +10,10 @@ use preserves::value::IOValueDomainCodec;
use preserves::value::PackedWriter;
use preserves::value::Reader;
use preserves::value::Writer;
use preserves::value::packed::annotated_iovalue_from_bytes;
use preserves::value;
use std::fs::File;
use std::io;
use std::io::Read;
use std::io::Seek;
use std::io;
#[path = "../tests/samples/mod.rs"]
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 bs = vec![];
fh.read_to_end(&mut bs).ok();
c.bench_function("decode samples.bin via bytes", |b| b.iter_with_large_drop(
|| annotated_iovalue_from_bytes(&bs[..]).unwrap()));
c.bench_function("decode samples.bin via bytes", |b| {
b.iter_with_large_drop(|| annotated_iovalue_from_bytes(&bs[..]).unwrap())
});
}
pub fn bench_decoder_file(c: &mut Criterion) {
let mut fh = File::open("../../../tests/samples.bin").unwrap();
c.bench_function("decode samples.bin via file", |b| b.iter_with_large_drop(|| {
fh.seek(io::SeekFrom::Start(0)).ok();
IOBinarySource::new(&mut fh).packed_iovalues().demand_next(true).unwrap()
}));
c.bench_function("decode samples.bin via file", |b| {
b.iter_with_large_drop(|| {
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) {
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(|| {
fh.seek(io::SeekFrom::Start(0)).ok();
IOBinarySource::new(&mut fh).packed_iovalues().demand_next(true).unwrap()
}));
c.bench_function("decode samples.bin via buffered file", |b| {
b.iter_with_large_drop(|| {
fh.seek(io::SeekFrom::Start(0)).ok();
IOBinarySource::new(&mut fh)
.packed_iovalues()
.demand_next(true)
.unwrap()
})
});
}
pub fn bench_encoder(c: &mut Criterion) {
let mut fh = File::open("../../../tests/samples.bin").unwrap();
let v = IOBinarySource::new(&mut fh).packed_iovalues().demand_next(true).unwrap();
c.bench_function("encode samples.bin", |b| b.iter_with_large_drop(
|| PackedWriter::encode_iovalue(&v).unwrap()));
let v = IOBinarySource::new(&mut fh)
.packed_iovalues()
.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) {
let mut fh = File::open("../../../tests/samples.bin").unwrap();
let mut bs = vec![];
fh.read_to_end(&mut bs).ok();
c.bench_function("deserialize samples.bin", |b| b.iter_with_large_drop(
|| de::from_bytes::<TestCases>(&bs[..]).unwrap()));
c.bench_function("deserialize samples.bin", |b| {
b.iter_with_large_drop(|| de::from_bytes::<TestCases>(&bs[..]).unwrap())
});
}
pub fn bench_ser(c: &mut Criterion) {
let mut fh = File::open("../../../tests/samples.bin").unwrap();
let v: TestCases = de::from_read(&mut fh).unwrap();
c.bench_function("serialize samples.bin", |b| b.iter_with_large_drop(|| {
let mut bs = vec![];
ser::to_writer(&mut PackedWriter::new(&mut bs), &v).unwrap();
bs
}));
c.bench_function("serialize samples.bin", |b| {
b.iter_with_large_drop(|| {
let mut bs = vec![];
ser::to_writer(&mut PackedWriter::new(&mut bs), &v).unwrap();
bs
})
});
}
pub fn bench_decoder_de(c: &mut Criterion) {
let mut fh = File::open("../../../tests/samples.bin").unwrap();
let mut bs = vec![];
fh.read_to_end(&mut bs).ok();
c.bench_function("decode-then-deserialize samples.bin", |b| b.iter_with_large_drop(
|| value::de::from_value::<TestCases>(&annotated_iovalue_from_bytes(&bs[..]).unwrap()).unwrap()));
c.bench_function("decode-then-deserialize samples.bin", |b| {
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) {
let mut fh = File::open("../../../tests/samples.bin").unwrap();
let v: TestCases = de::from_read(&mut fh).unwrap();
c.bench_function("serialize-then-encode samples.bin", |b| b.iter_with_large_drop(
|| PackedWriter::encode_iovalue(&value::ser::to_value(&v)).unwrap()));
c.bench_function("serialize-then-encode samples.bin", |b| {
b.iter_with_large_drop(|| PackedWriter::encode_iovalue(&value::ser::to_value(&v)).unwrap())
});
}
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,
bench_decoder_bytes, bench_decoder_file, bench_decoder_buffered_file,
bench_encoder);
criterion_group!(
codec,
bench_decoder_bytes,
bench_decoder_file,
bench_decoder_buffered_file,
bench_encoder
);
criterion_group!(serde, bench_de, bench_ser);
criterion_group!(codec_then_serde, bench_decoder_de, bench_ser_encoder);
criterion_group!{
criterion_group! {
name = large_testdata;
config = Criterion::default().sample_size(10);
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 serde::{Serialize, Deserialize};
use preserves::{
de,
value::{self, BinarySource, IOBinarySource, Reader},
};
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::io;
@ -10,7 +13,6 @@ enum Fruit {
Banana(Weight, Colour, u8),
// Peach,
#[serde(other)]
Unknown,
}
@ -33,7 +35,9 @@ enum Variety {
}
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);
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::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
use std::borrow::Cow;
use std::io;
use std::marker::PhantomData;
use super::value::boundary as B;
use super::value::reader::{BytesBinarySource, IOBinarySource, Reader};
use super::value::{IOValue, IOValueDomainCodec, PackedReader, TextReader, ViaCodec};
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource};
pub use super::error::Error;
@ -18,31 +18,39 @@ pub struct Deserializer<'de, 'r, R: Reader<'de, IOValue>> {
phantom: PhantomData<&'de ()>,
}
pub fn from_bytes<'de, T>(bytes: &'de [u8]) ->
Result<T>
pub fn from_bytes<'de, T>(bytes: &'de [u8]) -> Result<T>
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> {
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>
pub fn from_text<'de, T>(text: &'de str) -> Result<T>
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) ->
Result<T>
pub fn from_read<'de, 'r, IOR: io::Read + io::Seek, T>(read: &'r mut IOR) -> Result<T>
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 t = T::deserialize(&mut de)?;
@ -51,83 +59,113 @@ where
impl<'r, 'de, R: Reader<'de, IOValue>> Deserializer<'de, 'r, R> {
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>>
serde::de::Deserializer<'de>
impl<'r, 'de, 'a, R: Reader<'de, IOValue>> serde::de::Deserializer<'de>
for &'a mut Deserializer<'de, 'r, R>
{
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
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()? {
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)
}
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()? {
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())
}
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()? {
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)?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
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 result = visitor.visit_unit::<Error>()?;
@ -173,8 +222,9 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
Ok(result)
}
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let b = self.read.open_simple_record(name, Some(0))?;
let result = visitor.visit_unit::<Error>()?;
@ -182,16 +232,18 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
Ok(result)
}
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
match super::value::magic::transmit_input_value(
name, || Ok(self.read.demand_next(true)?))?
{
match super::value::magic::transmit_input_value(name, || {
Ok(self.read.demand_next(true)?)
})? {
Some(v) => visitor.visit_u64(v),
None => {
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)?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
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,
// too, and reconstruct them as Rust Sets on the visitor side.
let i = self.read.open_sequence_or_set()?;
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 mut seq = Seq::new(self, b, B::Item::RecordField);
@ -215,8 +272,14 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
Ok(result)
}
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
fn deserialize_tuple_struct<V>(
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 mut seq = Seq::new(self, b, B::Item::RecordField);
@ -225,18 +288,24 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
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()?;
let mut seq = Seq::new(self, B::Type::default(), B::Item::DictionaryKey);
let result = visitor.visit_map(&mut seq)?;
Ok(result)
}
fn deserialize_struct<V>(self,
name: &'static str,
fields: &'static [&'static str],
visitor: V)
-> Result<V::Value> where V: Visitor<'de>
fn deserialize_struct<V>(
self,
name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
let b = self.read.open_simple_record(name, Some(fields.len()))?;
let mut seq = Seq::new(self, b, B::Item::RecordField);
@ -245,16 +314,21 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
Ok(result)
}
fn deserialize_enum<V>(self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V)
-> Result<V::Value> where V: Visitor<'de>
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
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()? {
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()
}
@ -286,8 +362,9 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> Seq<'de, 'r, 'a, R> {
Ok(())
}
fn next_item<T>(&mut self, seed: T) ->
Result<Option<T::Value>> where T: DeserializeSeed<'de>
fn next_item<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'de>,
{
match self.de.read.close_compound(&mut self.b, &self.i)? {
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> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) ->
Result<Option<T::Value>> where T: DeserializeSeed<'de>
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'de>,
{
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> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) ->
Result<Option<K::Value>> where K: DeserializeSeed<'de>
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where
K: DeserializeSeed<'de>,
{
self.i = B::Item::DictionaryKey;
self.next_item(seed)
}
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>,
{
self.i = B::Item::DictionaryValue;
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 Variant = Seq<'de, 'r, 'a, R>;
fn variant_seed<V>(self, seed: V)
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
where
V: DeserializeSeed<'de>,
{
let b = self.read.open_record(None)?;
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()
}
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)? {
None => Err(Error::MissingItem),
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) ->
Result<V::Value>
fn tuple_variant<V>(mut self, _len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
V: Visitor<'de>,
{
let result = visitor.visit_seq(&mut self)?;
self.skip_remainder()?;
Ok(result)
}
fn struct_variant<V>(mut self, _fields: &'static [&'static str], visitor: V) ->
Result<V::Value>
fn struct_variant<V>(mut self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
where
V: Visitor<'de>
V: Visitor<'de>,
{
let result = visitor.visit_seq(&mut self)?;
self.skip_remainder()?;

View File

@ -20,20 +20,24 @@ impl HexParser {
let mut buf_full = false;
for c in s.chars() {
match c.to_digit(16) {
None =>
match self {
HexParser::Liberal => (),
HexParser::WhitespaceAllowed => if !c.is_whitespace() { return None },
HexParser::Strict => return None,
},
Some(nibble) =>
None => match self {
HexParser::Liberal => (),
HexParser::WhitespaceAllowed => {
if !c.is_whitespace() {
return None;
}
}
HexParser::Strict => return None,
},
Some(nibble) => {
if buf_full {
result.push(buf << 4 | (nibble as u8));
buf_full = false;
} else {
buf = nibble as u8;
buf_full = true;
},
}
}
}
}
if buf_full {
@ -76,42 +80,89 @@ impl HexFormatter {
mod test {
use super::*;
#[test] fn test_decode_packed() {
#[test]
fn test_decode_packed() {
let s = "01ab00ff";
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]));
}
#[test] fn test_decode_whitespace() {
#[test]
fn test_decode_whitespace() {
let s = "01ab 00ff";
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]));
}
#[test] fn test_decode_liberal() {
#[test]
fn test_decode_liberal() {
let s = "01ab zz 00ff";
assert_eq!(HexParser::Strict.decode(s), None);
assert_eq!(HexParser::WhitespaceAllowed.decode(s), None);
assert_eq!(HexParser::Liberal.decode(s), Some(vec![1, 171, 0, 255]));
}
#[test] fn test_encode_lines() {
assert_eq!(HexFormatter::Lines(10).encode(&vec![0x5a; 11]), "5a5a5a5a5a\n5a5a5a5a5a\n5a");
assert_eq!(HexFormatter::Lines(10).encode(&vec![0x5a; 10]), "5a5a5a5a5a\n5a5a5a5a5a");
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_lines() {
assert_eq!(
HexFormatter::Lines(10).encode(&vec![0x5a; 11]),
"5a5a5a5a5a\n5a5a5a5a5a\n5a"
);
assert_eq!(
HexFormatter::Lines(10).encode(&vec![0x5a; 10]),
"5a5a5a5a5a\n5a5a5a5a5a"
);
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() {
assert_eq!(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");
#[test]
fn test_encode_packed() {
assert_eq!(
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::writer::{Writer, CompoundWriter};
use super::value::writer::{CompoundWriter, Writer};
use super::value::IOValueDomainCodec;
use serde::Serialize;
pub use super::error::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)?)
}
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))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
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)?)
}
fn serialize_unit_variant(self,
_name: &'static str,
_variant: u32,
variant_name: &'static str) ->
Result<Self::Ok>
{
fn serialize_unit_variant(
self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(0))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
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)?)
}
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
Result<Self::Ok> where T: Serialize
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<Self::Ok>
where
T: Serialize,
{
match super::value::magic::receive_output_value(name, value) {
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,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
value: &T) ->
Result<Self::Ok> where T: Serialize
fn serialize_newtype_variant<T: ?Sized>(
self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
value: &T,
) -> Result<Self::Ok>
where
T: Serialize,
{
let mut c = self.write.start_record(Some(1))?;
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))
}
fn serialize_tuple_struct(self, name: &'static str, count: usize) ->
Result<Self::SerializeTupleStruct>
{
fn serialize_tuple_struct(
self,
name: &'static str,
count: usize,
) -> Result<Self::SerializeTupleStruct> {
let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(name)?;
Ok(SerializeCompound::rec(self, c))
}
fn serialize_tuple_variant(self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize) ->
Result<Self::SerializeTupleVariant>
{
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize,
) -> Result<Self::SerializeTupleVariant> {
let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
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> {
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> {
@ -235,13 +248,13 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
Ok(SerializeCompound::rec(self, c))
}
fn serialize_struct_variant(self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize) ->
Result<Self::SerializeStructVariant>
{
fn serialize_struct_variant(
self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize,
) -> Result<Self::SerializeStructVariant> {
let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?;
@ -253,7 +266,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'w,
type Ok = ();
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.d.boundary(&self.b)?;
to_writer(&mut self.d, key)?;
@ -261,7 +277,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'w,
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.d.boundary(&self.b)?;
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<()>
where T: Serialize
where
T: Serialize,
{
self.b.opening = Some(self.i.clone());
match &mut self.c {
SequenceVariant::Sequence(w) => { w.boundary(&self.b)?; to_writer(w, value)?; }
SequenceVariant::Record(w) => { w.boundary(&self.b)?; to_writer(w, value)?; }
SequenceVariant::Sequence(w) => {
w.boundary(&self.b)?;
to_writer(w, value)?;
}
SequenceVariant::Record(w) => {
w.boundary(&self.b)?;
to_writer(w, value)?;
}
}
self.b.shift(None);
Ok(())
@ -325,7 +351,8 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeStruct for SerializeCompound<'a, 'w
type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize
where
T: Serialize,
{
self.extend(value)
}
@ -340,7 +367,8 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeStructVariant for SerializeCompound
type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize
where
T: Serialize,
{
self.extend(value)
}
@ -354,7 +382,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeTuple for SerializeCompound<'a, 'w,
type Ok = ();
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)
}
@ -367,7 +398,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeTupleStruct for SerializeCompound<'
type Ok = ();
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)
}
@ -380,7 +414,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeTupleVariant for SerializeCompound<
type Ok = ();
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)
}
@ -393,7 +430,10 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeSeq for SerializeCompound<'a, 'w, W
type Ok = ();
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)
}

View File

@ -1,6 +1,6 @@
use crate::value::{self, to_value, IOValue, UnwrappedIOValue};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
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>
where

View File

@ -4,26 +4,39 @@ use crate::value::{IOValue, NestedValue};
pub struct Symbol(pub String);
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)
}
}
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 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()))
}
}
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;
Symbol(s.to_string()).serialize(serializer)
}
pub fn deserialize<'de, D>(deserializer: D) ->
Result<String, D::Error> where D: serde::Deserializer<'de>
pub fn deserialize<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::Deserialize;
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::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::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
use std::iter::Iterator;
pub type Result<T> = std::result::Result<T, Error>;
@ -11,7 +11,9 @@ pub struct Deserializer<'de> {
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 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>
where F: FnOnce(&'de UnwrappedIOValue) -> Option<T>
where
F: FnOnce(&'de UnwrappedIOValue) -> Option<T>,
{
f(self.input.value()).ok_or_else(
|| Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", self.input))))
f(self.input.value()).ok_or_else(|| {
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;
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();
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::String(ref s) => visitor.visit_str(&s),
Value::ByteString(_) => self.deserialize_bytes(visitor),
Value::Record(_) =>
Value::Record(_) => {
if v.is_simple_record("tuple", Some(0)) {
self.deserialize_unit(visitor)
} else if v.is_simple_record("UnicodeScalar", Some(1)) {
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)
} 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 {
Err(Error::CannotDeserializeAny)
}
}
Value::Sequence(ref v) => visitor.visit_seq(VecSeq::new(self, v.iter())),
Value::Dictionary(ref d) => visitor.visit_map(DictMap::new(self, d)),
_ => 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() {
Some(n) => Err(Error::NumberOutOfRange(n.into())),
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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()?)
}
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() {
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() {
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()?)
}
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()?;
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)
}
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()?;
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())
}
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()? {
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))?;
visitor.visit_unit()
}
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let _fs = self.input.value().to_simple_record(name, Some(0))?;
visitor.visit_unit()
}
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
match super::magic::transmit_input_value(name, || Ok(self.input.clone()))? {
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() {
Some(vs) => visitor.visit_seq(VecSeq::new(self, vs.iter())),
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))?;
visitor.visit_seq(VecSeq::new(self, fs.iter()))
}
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
fn deserialize_tuple_struct<V>(
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))?;
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()?;
visitor.visit_map(DictMap::new(self, d))
}
fn deserialize_struct<V>(self,
name: &'static str,
fields: &'static [&'static str],
visitor: V)
-> Result<V::Value> where V: Visitor<'de>
fn deserialize_struct<V>(
self,
name: &'static str,
fields: &'static [&'static str],
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()))
}
fn deserialize_enum<V>(self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V)
-> Result<V::Value> where V: Visitor<'de>
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
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()?)
}
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()
}
@ -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> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) ->
Result<Option<T::Value>>
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'de>
T: DeserializeSeed<'de>,
{
match self.iter.next() {
None => Ok(None),
@ -293,15 +367,20 @@ pub struct DictMap<'a, 'de: 'a> {
impl<'de, 'a> DictMap<'a, 'de> {
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> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K)
-> Result<Option<K::Value>> where K: DeserializeSeed<'de>
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where
K: DeserializeSeed<'de>,
{
match self.iter.next() {
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();
self.pending = None;
self.de.input = v;
@ -325,8 +407,9 @@ impl<'a, 'de> EnumAccess<'de> for &'a mut Deserializer<'de> {
type Error = Error;
type Variant = Self;
fn variant_seed<V>(self, seed: V)
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
where
V: DeserializeSeed<'de>,
{
let r = self.check(|v| v.as_record(None), ExpectedKind::Record(None))?;
let v = self.input;
@ -344,19 +427,37 @@ impl<'a, 'de> VariantAccess<'de> for &'a mut Deserializer<'de> {
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)))?;
self.input = &r.fields()[0];
seed.deserialize(&mut *self)
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
visitor.visit_seq(VecSeq::new(self, self.input.value().as_record(None).unwrap().fields().iter()))
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
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)
-> Result<V::Value> where V: Visitor<'de>
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
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 super::packed;
use super::BinarySource;
use super::BytesBinarySource;
use super::Embeddable;
@ -7,13 +8,9 @@ use super::IOValue;
use super::NestedValue;
use super::Reader;
use super::Writer;
use super::packed;
pub trait DomainParse<D: Embeddable> {
fn parse_embedded(
&mut self,
v: &IOValue,
) -> io::Result<D>;
fn parse_embedded(&mut self, v: &IOValue) -> io::Result<D>;
}
pub trait DomainDecode<D: Embeddable> {
@ -25,18 +22,11 @@ pub trait DomainDecode<D: Embeddable> {
}
pub trait DomainEncode<D: Embeddable> {
fn encode_embedded<W: Writer>(
&mut self,
w: &mut W,
d: &D,
) -> io::Result<()>;
fn encode_embedded<W: Writer>(&mut self, w: &mut W, d: &D) -> io::Result<()>;
}
impl<'a, D: Embeddable, T: DomainParse<D>> DomainParse<D> for &'a mut T {
fn parse_embedded(
&mut self,
v: &IOValue,
) -> io::Result<D> {
fn parse_embedded(&mut self, v: &IOValue) -> io::Result<D> {
(**self).parse_embedded(v)
}
}
@ -61,7 +51,9 @@ impl<D: Embeddable> DomainEncode<D> for DebugDomainEncode {
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> {
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 {
fn encode_embedded<W: Writer>(
&mut self,
w: &mut W,
d: &IOValue,
) -> io::Result<()> {
fn encode_embedded<W: Writer>(&mut self, w: &mut W, d: &IOValue) -> io::Result<()> {
w.write(self, d)
}
}
@ -97,17 +85,19 @@ impl<D: Embeddable> DomainDecode<D> for NoEmbeddedDomainCodec {
_src: &'src mut S,
_read_annotations: bool,
) -> 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 {
fn encode_embedded<W: Writer>(
&mut self,
_w: &mut W,
_d: &D,
) -> io::Result<()> {
Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))
fn encode_embedded<W: Writer>(&mut self, _w: &mut W, _d: &D) -> 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> {
fn parse_embedded(
&mut self,
v: &IOValue,
) -> io::Result<D> {
fn parse_embedded(&mut self, v: &IOValue) -> io::Result<D> {
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,
read_annotations: bool,
) -> 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)
}
}

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 {
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) };
Ok(*b)
}
}
#[inline(always)]
pub fn output_value<S: serde::Serializer>(serializer: S, v: IOValue) ->
Result<S::Ok, S::Error>
{
pub fn output_value<S: serde::Serializer>(serializer: S, v: IOValue) -> Result<S::Ok, S::Error> {
serializer.serialize_newtype_struct(MAGIC, &(Box::into_raw(Box::new(v)) as u64))
}
#[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)
}
@ -32,7 +32,8 @@ pub fn input_value<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<
#[inline]
pub fn receive_output_value<T: ?Sized>(name: &'static str, magic_value: &T) -> Option<IOValue> {
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;
Some(v)
} else {
@ -42,7 +43,8 @@ pub fn receive_output_value<T: ?Sized>(name: &'static str, magic_value: &T) -> O
#[inline]
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 {
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))
} else {
let maybe_merged = match v_val {
Value::Record(rv) =>
Some(Value::Record(Record(merge_seqs(rv.0, w_val.into_record()?.0)?))),
Value::Sequence(vs) =>
Some(Value::Sequence(merge_seqs(vs, w_val.into_sequence()?)?)),
Value::Set(_vs) =>
None, // unsure how to merge sets
Value::Record(rv) => Some(Value::Record(Record(merge_seqs(
rv.0,
w_val.into_record()?.0,
)?))),
Value::Sequence(vs) => Some(Value::Sequence(merge_seqs(vs, w_val.into_sequence()?)?)),
Value::Set(_vs) => None, // unsure how to merge sets
Value::Dictionary(vs) => {
let mut ws = w_val.into_dictionary()?;
let mut rs = Map::new();
for (k, vv) in vs.into_iter() {
match ws.remove(&k) {
Some(wv) => { rs.insert(k, merge2(vv, wv)?); }
None => { rs.insert(k, vv); }
Some(wv) => {
rs.insert(k, merge2(vv, wv)?);
}
None => {
rs.insert(k, vv);
}
}
}
rs.extend(ws.into_iter());

View File

@ -2,6 +2,7 @@ pub mod boundary;
pub mod de;
pub mod domain;
pub mod magic;
pub mod merge;
pub mod packed;
pub mod reader;
pub mod repr;
@ -10,14 +11,13 @@ pub mod signed_integer;
pub mod suspendable;
pub mod text;
pub mod writer;
pub mod merge;
pub use de::Deserializer;
pub use de::from_value;
pub use de::Deserializer;
pub use domain::DebugDomainEncode;
pub use domain::DomainDecode;
pub use domain::DomainEncode;
pub use domain::DomainParse;
pub use domain::DebugDomainEncode;
pub use domain::FromStrDomainParse;
pub use domain::IOValueDomainCodec;
pub use domain::NoEmbeddedDomainCodec;
@ -50,14 +50,16 @@ pub use repr::Set;
pub use repr::UnwrappedIOValue;
pub use repr::Value;
pub use repr::ValueClass;
pub use ser::Serializer;
pub use ser::to_value;
pub use ser::Serializer;
pub use text::TextReader;
pub use text::TextWriter;
pub use writer::Writer;
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()
}

View File

@ -1,4 +1,4 @@
use std::convert::{TryFrom, From};
use std::convert::{From, TryFrom};
use std::io;
#[derive(Debug, PartialEq, Eq)]
@ -27,7 +27,10 @@ pub struct InvalidTag(u8);
impl From<InvalidTag> for io::Error {
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),
0xb6 => Ok(Self::Set),
0xb7 => Ok(Self::Dictionary),
_ => Err(InvalidTag(v))
_ => Err(InvalidTag(v)),
}
}
}
@ -74,7 +77,13 @@ impl From<Tag> for u8 {
Tag::End => 0x84,
Tag::Annotation => 0x85,
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::SignedInteger => 0xb0,
Tag::String => 0xb1,

View File

@ -13,7 +13,9 @@ pub fn from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &[u8],
decode_embedded: Dec,
) -> 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> {
@ -24,7 +26,9 @@ pub fn annotated_from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &[u8],
decode_embedded: Dec,
) -> 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> {

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::traits::cast::{FromPrimitive, ToPrimitive};
@ -9,36 +9,29 @@ use std::convert::TryInto;
use std::io;
use std::marker::PhantomData;
use super::constants::Tag;
use super::super::{
CompoundClass,
DomainDecode,
Map,
NestedValue,
Record,
Set,
Value,
boundary as B,
reader::{
Token,
BinarySource,
Reader,
ReaderResult,
},
reader::{BinarySource, Reader, ReaderResult, Token},
repr::Annotations,
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 decode_embedded: Dec,
phantom: PhantomData<&'de N>,
}
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>>
BinarySource<'de>
for PackedReader<'de, 'src, N, Dec, S>
BinarySource<'de> for PackedReader<'de, 'src, N, Dec, S>
{
type Mark = S::Mark;
#[inline(always)]
@ -71,10 +64,16 @@ fn out_of_range<I: Into<BigInt>>(i: I) -> error::Error {
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)]
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)]
@ -87,7 +86,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
fn expected(&mut self, k: ExpectedKind) -> error::Error {
match self.demand_next(true) {
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()?;
acc |= ((v & 0x7f) as usize) << shift;
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 => {
self.skip()?;
self.skip_value()?;
},
}
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()?;
if actual_tag == expected_tag {
self.skip()?;
@ -159,20 +159,33 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
if (bs[0] & 0x80) == 0 {
// Positive or zero.
let mut i = 0;
while i < count && bs[i] == 0 { i += 1; }
while i < count && bs[i] == 0 {
i += 1;
}
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 {
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 {
// Negative.
let mut i = 0;
while i < count && bs[i] == 0xff { i += 1; }
while i < count && bs[i] == 0xff {
i += 1;
}
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 {
Ok(SignedInteger::from(Cow::Owned(BigInt::from_signed_bytes_be(&bs))))
Ok(SignedInteger::from(Cow::Owned(
BigInt::from_signed_bytes_be(&bs),
)))
}
}
} else {
@ -188,7 +201,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
#[inline(always)]
fn next_unsigned<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T>
where
F: FnOnce(u128) -> Option<T>
F: FnOnce(u128) -> Option<T>,
{
let tag = self.peek_next_nonannotation_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))?;
f(i).ok_or_else(|| out_of_range(i))
}
_ => Err(self.expected(ExpectedKind::SignedInteger))
_ => Err(self.expected(ExpectedKind::SignedInteger)),
}
}
#[inline(always)]
fn next_signed<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T>
where
F: FnOnce(i128) -> Option<T>
F: FnOnce(i128) -> Option<T>,
{
let tag = self.peek_next_nonannotation_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))?;
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>>
Reader<'de, N>
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> Reader<'de, N>
for PackedReader<'de, 'src, N, Dec, S>
{
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)?
}
}
Tag::Embedded => {
Value::Embedded(self.decode_embedded.decode_embedded(self.source, read_annotations)?).wrap()
}
Tag::Embedded => Value::Embedded(
self.decode_embedded
.decode_embedded(self.source, read_annotations)?,
)
.wrap(),
Tag::SmallInteger(v) => {
// TODO: prebuild these in value.rs
Value::from(v).wrap()
@ -335,27 +349,35 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
}
Tag::Record => {
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() {
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()
}
Tag::Sequence => {
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()
}
Tag::Set => {
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()
}
Tag::Dictionary => {
let mut d = Map::new();
while let Some(k) = 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")),
}
}
@ -386,8 +408,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
self.skip()?;
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()?)? {
Tag::Embedded => {
self.skip()?;
Token::Embedded(self.decode_embedded.decode_embedded(
self.source,
read_embedded_annotations)?)
Token::Embedded(
self.decode_embedded
.decode_embedded(self.source, read_embedded_annotations)?,
)
}
Tag::False |
Tag::True |
Tag::Float |
Tag::Double |
Tag::SmallInteger(_) |
Tag::MediumInteger(_) |
Tag::SignedInteger |
Tag::String |
Tag::ByteString |
Tag::Symbol =>
Token::Atom(self.demand_next(false)?),
Tag::False
| Tag::True
| Tag::Float
| Tag::Double
| Tag::SmallInteger(_)
| Tag::MediumInteger(_)
| Tag::SignedInteger
| Tag::String
| Tag::ByteString
| Tag::Symbol => Token::Atom(self.demand_next(false)?),
Tag::Record => { self.skip()?; Token::Compound(CompoundClass::Record) }
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::Record => {
self.skip()?;
Token::Compound(CompoundClass::Record)
}
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 => {
self.skip()?;
self.skip_annotations()?;
continue
continue;
}
})
});
}
}
@ -489,8 +525,14 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
#[inline(always)]
fn next_boolean(&mut self) -> ReaderResult<bool> {
match self.peek_next_nonannotation_tag()? {
Tag::False => { self.skip()?; Ok(false) }
Tag::True => { self.skip()?; Ok(true) }
Tag::False => {
self.skip()?;
Ok(false)
}
Tag::True => {
self.skip()?;
Ok(true)
}
_ => Err(self.expected(ExpectedKind::Boolean)),
}
}
@ -511,21 +553,41 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
let count = self.varint()?;
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_i16(&mut self) -> ReaderResult<i16> { 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_i8(&mut self) -> ReaderResult<i8> {
self.next_signed(|n| n.to_i8())
}
fn next_i16(&mut self) -> ReaderResult<i16> {
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_u16(&mut self) -> ReaderResult<u16> { 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_u8(&mut self) -> ReaderResult<u8> {
self.next_unsigned(|n| n.to_u8())
}
fn next_u16(&mut self) -> ReaderResult<u16> {
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> {
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];
self.readbytes_into(&mut bs)?;
Ok(f32::from_bits(u32::from_be_bytes(bs)))
},
}
Tag::Double => {
self.skip()?;
let mut bs = [0; 8];
self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs)) as f32)
},
}
_ => 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];
self.readbytes_into(&mut bs)?;
Ok(f32::from_bits(u32::from_be_bytes(bs)) as f64)
},
}
Tag::Double => {
self.skip()?;
let mut bs = [0; 8];
self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs)))
},
}
_ => Err(self.expected(ExpectedKind::Double)),
}
}
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]>> {
@ -572,16 +636,20 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
}
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)]
fn decodestr(cow: Cow<'_, [u8]>) -> io::Result<Cow<'_, str>> {
match cow {
Cow::Borrowed(bs) =>
Ok(Cow::Borrowed(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::Borrowed(bs) => Ok(Cow::Borrowed(
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"))?,
)),
}
}

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::cast::ToPrimitive;
use std::convert::TryInto;
use std::io;
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>);
@ -51,7 +51,9 @@ impl<W: io::Write> PackedWriter<W> {
#[inline(always)]
pub fn write_medium_integer(&mut self, bs: &[u8]) -> io::Result<()> {
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.w().write_all(bs)
}
@ -109,7 +111,9 @@ impl BinaryOrderWriter {
#[inline(always)]
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().sort();
for bs in self.items() {
@ -158,13 +162,11 @@ impl CompoundWriter for BinaryOrderWriter {
#[inline(always)]
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
match b.closing {
Some(B::Item::DictionaryValue) |
Some(B::Item::RecordField) |
Some(B::Item::SequenceValue) |
Some(B::Item::SetValue) =>
self.items_mut().push(vec![]),
_ =>
()
Some(B::Item::DictionaryValue)
| Some(B::Item::RecordField)
| Some(B::Item::SequenceValue)
| Some(B::Item::SetValue) => self.items_mut().push(vec![]),
_ => (),
}
Ok(())
}
@ -276,14 +278,13 @@ impl Writer for BinaryOrderWriter {
}
macro_rules! fits_in_bytes {
($v:ident, $limit:literal) => ({
($v:ident, $limit:literal) => {{
let bits = $limit * 8 - 1;
$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 RecWriter = Self;
type SeqWriter = Self;
@ -321,120 +322,166 @@ impl<W: io::Write> Writer for PackedWriter<W>
#[inline(always)]
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])
}
#[inline(always)]
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])
}
#[inline(always)]
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])
}
#[inline(always)]
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])
}
#[inline(always)]
fn write_i32(&mut self, v: i32) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) }
if fits_in_bytes!(v, 3) {
return self.write_medium_integer(&[(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
if let Ok(w) = v.try_into() {
return self.write_i16(w);
}
self.write_medium_integer(&[(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8])
if fits_in_bytes!(v, 3) {
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,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8,
])
}
#[inline(always)]
fn write_u32(&mut self, v: u32) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) }
self.write_medium_integer(&[0,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8])
if let Ok(w) = v.try_into() {
return self.write_i32(w);
}
self.write_medium_integer(&[
0,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8,
])
}
#[inline(always)]
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) {
return self.write_medium_integer(&[(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
return self.write_medium_integer(&[
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8,
]);
}
if fits_in_bytes!(v, 6) {
return self.write_medium_integer(&[(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
return self.write_medium_integer(&[
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8,
]);
}
if fits_in_bytes!(v, 7) {
return self.write_medium_integer(&[(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
return self.write_medium_integer(&[
(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8,
]);
}
self.write_medium_integer(&[(v >> 56) as u8,
(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8])
self.write_medium_integer(&[
(v >> 56) as u8,
(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8,
])
}
#[inline(always)]
fn write_u64(&mut self, v: u64) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) }
self.write_medium_integer(&[0,
(v >> 56) as u8,
(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8])
if let Ok(w) = v.try_into() {
return self.write_i64(w);
}
self.write_medium_integer(&[
0,
(v >> 56) as u8,
(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8,
])
}
#[inline(always)]
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();
if fits_in_bytes!(v, 9) { return self.write_medium_integer(&bs[7..]); }
if fits_in_bytes!(v, 10) { return self.write_medium_integer(&bs[6..]); }
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..]); }
if fits_in_bytes!(v, 9) {
return self.write_medium_integer(&bs[7..]);
}
if fits_in_bytes!(v, 10) {
return self.write_medium_integer(&bs[6..]);
}
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)
}
#[inline(always)]
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();
self.write_tag(Tag::SignedInteger)?;
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<()> {
match v.to_i8() {
Some(n) => self.write_i8(n),
None => {
match v.to_i128() {
Some(n) => self.write_i128(n),
None => self.write_atom(Tag::SignedInteger, &v.to_signed_bytes_be()),
}
}
None => match v.to_i128() {
Some(n) => self.write_i128(n),
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::io;
use std::marker::PhantomData;
use super::boundary as B;
use super::signed_integer::SignedInteger;
use super::CompoundClass;
use super::DomainDecode;
use super::DomainParse;
@ -13,8 +15,6 @@ use super::IOValue;
use super::IOValueDomainCodec;
use super::NestedValue;
use super::ViaCodec;
use super::boundary as B;
use super::signed_integer::SignedInteger;
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> {
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_u8(&mut self) -> ReaderResult<u8> { self.demand_next(false)?.value().to_u8() }
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_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_i8(&mut self) -> ReaderResult<i8> {
self.demand_next(false)?.value().to_i8()
}
fn next_u8(&mut self) -> ReaderResult<u8> {
self.demand_next(false)?.value().to_u8()
}
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_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>> {
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]>> {
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>> {
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 label: &str = &self.next_symbol()?;
match label {
@ -110,29 +145,30 @@ pub trait Reader<'de, N: NestedValue> {
self.ensure_complete(b, &B::Item::RecordField)?;
Ok(None)
}
"Some" =>
Ok(Some(b)),
_ =>
Err(error::Error::Expected(ExpectedKind::Option,
Received::ReceivedRecordWithLabel(label.to_owned()))),
"Some" => Ok(Some(b)),
_ => Err(error::Error::Expected(
ExpectedKind::Option,
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 label: &str = &self.next_symbol()?;
if label == name {
Ok(b)
} else {
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity),
Received::ReceivedRecordWithLabel(label.to_owned())))
Err(error::Error::Expected(
ExpectedKind::SimpleRecord(name.to_owned(), arity),
Received::ReceivedRecordWithLabel(label.to_owned()),
))
}
}
fn configured(self, read_annotations: bool) -> ConfiguredReader<'de, N, Self>
where
Self: std::marker::Sized
Self: std::marker::Sized,
{
ConfiguredReader {
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 {
type Mark;
fn mark(&mut self) -> io::Result<Self::Mark>;
@ -236,9 +271,9 @@ pub trait BinarySource<'de>: Sized {
super::PackedReader::new(self, decode_embedded)
}
fn packed_iovalues(&mut self) ->
super::PackedReader<'de, '_, IOValue, IOValueDomainCodec, Self>
{
fn packed_iovalues(
&mut self,
) -> super::PackedReader<'de, '_, IOValue, IOValueDomainCodec, Self> {
self.packed(IOValueDomainCodec)
}
@ -249,9 +284,9 @@ pub trait BinarySource<'de>: Sized {
super::TextReader::new(self, decode_embedded)
}
fn text_iovalues(&mut self) ->
super::TextReader<'de, '_, IOValue, ViaCodec<IOValueDomainCodec>, Self>
{
fn text_iovalues(
&mut self,
) -> super::TextReader<'de, '_, IOValue, ViaCodec<IOValueDomainCodec>, Self> {
self.text::<IOValue, _>(ViaCodec::new(IOValueDomainCodec))
}
}
@ -285,7 +320,9 @@ impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.buf.is_none() { unreachable!(); }
if self.buf.is_none() {
unreachable!();
}
self.buf = None;
Ok(())
}
@ -310,7 +347,9 @@ impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
#[inline(always)]
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];
self.read.read_exact(&mut bs)?;
Ok(Cow::Owned(bs))
@ -318,7 +357,9 @@ impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
#[inline(always)]
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)
}
}
@ -351,7 +392,9 @@ impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.index >= self.bytes.len() { unreachable!(); }
if self.index >= self.bytes.len() {
unreachable!();
}
self.index += 1;
Ok(())
}
@ -370,7 +413,7 @@ impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
if self.index + count > self.bytes.len() {
Err(io_eof())
} else {
let bs = &self.bytes[self.index..self.index+count];
let bs = &self.bytes[self.index..self.index + count];
self.index += count;
Ok(Cow::Borrowed(bs))
}
@ -382,7 +425,7 @@ impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
if self.index + count > self.bytes.len() {
Err(io_eof())
} 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;
Ok(())
}

View File

@ -14,16 +14,16 @@ use std::string::String;
use std::sync::Arc;
use std::vec::Vec;
pub use std::collections::BTreeSet as Set;
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::FromStrDomainParse;
use super::IOValueDomainCodec;
use super::TextWriter;
use super::Writer;
use super::signed_integer::SignedInteger;
use super::text;
use crate::error::{Error, ExpectedKind, Received};
pub trait Domain: Sized + Debug + Eq + Hash + Ord {
@ -45,12 +45,18 @@ pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord {
type Embedded: Embeddable;
#[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()
}
#[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()
}
@ -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>
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>
where
F: FnMut(&Self::Embedded) -> Result<(), Err>
F: FnMut(&Self::Embedded) -> Result<(), Err>,
{
match &self.annotations().0 {
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)
}
@ -201,7 +214,10 @@ impl<N> Record<N> {
}
#[inline(always)]
pub fn finish(self) -> Value<N> where N: NestedValue {
pub fn finish(self) -> Value<N>
where
N: NestedValue,
{
Value::Record(self)
}
}
@ -234,8 +250,12 @@ impl Ord for Float {
fn cmp(&self, other: &Self) -> Ordering {
let mut a: u32 = self.0.to_bits();
let mut b: u32 = other.0.to_bits();
if a & 0x8000_0000 != 0 { a ^= 0x7fff_ffff; }
if b & 0x8000_0000 != 0 { b ^= 0x7fff_ffff; }
if a & 0x8000_0000 != 0 {
a ^= 0x7fff_ffff;
}
if b & 0x8000_0000 != 0 {
b ^= 0x7fff_ffff;
}
(a as i32).cmp(&(b as i32))
}
}
@ -276,8 +296,12 @@ impl Ord for Double {
fn cmp(&self, other: &Self) -> Ordering {
let mut a: u64 = self.0.to_bits();
let mut b: u64 = other.0.to_bits();
if a & 0x8000_0000_0000_0000 != 0 { a ^= 0x7fff_ffff_ffff_ffff; }
if b & 0x8000_0000_0000_0000 != 0 { b ^= 0x7fff_ffff_ffff_ffff; }
if a & 0x8000_0000_0000_0000 != 0 {
a ^= 0x7fff_ffff_ffff_ffff;
}
if b & 0x8000_0000_0000_0000 != 0 {
b ^= 0x7fff_ffff_ffff_ffff;
}
(a as i64).cmp(&(b as i64))
}
}
@ -290,42 +314,162 @@ impl PartialOrd 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> { 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<&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> { 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<f32> for Value<N> {
fn from(v: f32) -> Self {
Value::Float(Float::from(v))
}
}
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<i8> for Value<N> { fn from(v: i8) -> Self { Value::from(i128::from(v)) } }
impl<N: NestedValue> From<u16> for Value<N> { fn from(v: u16) -> Self { 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<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<u8> for Value<N> {
fn from(v: u8) -> Self {
Value::from(i128::from(v))
}
}
impl<N: NestedValue> From<i8> for Value<N> {
fn from(v: i8) -> Self {
Value::from(i128::from(v))
}
}
impl<N: NestedValue> From<u16> for Value<N> {
fn from(v: u16) -> Self {
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<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<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<&str> for Value<N> {
fn from(v: &str) -> Self {
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<N>> for Value<N> { fn from(v: Vec<N>) -> Self { 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> From<Vec<N>> for Value<N> {
fn from(v: Vec<N>) -> Self {
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> {
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>>
std::str::FromStr for Value<N>
impl<
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;
@ -369,14 +516,14 @@ impl<N: NestedValue> Value<N> {
pub fn children(&self) -> Vec<N> {
match self {
Value::Boolean(_) |
Value::Float(_) |
Value::Double(_) |
Value::SignedInteger(_) |
Value::String(_) |
Value::ByteString(_) |
Value::Symbol(_) |
Value::Embedded(_) => vec![],
Value::Boolean(_)
| Value::Float(_)
| Value::Double(_)
| Value::SignedInteger(_)
| Value::String(_)
| Value::ByteString(_)
| Value::Symbol(_)
| Value::Embedded(_) => vec![],
Value::Record(r) => r.fields().to_vec(),
Value::Sequence(vs) => vs.clone(),
@ -386,7 +533,10 @@ impl<N: NestedValue> Value<N> {
}
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)]
@ -414,7 +564,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
@ -442,7 +593,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
@ -490,7 +642,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
@ -538,7 +691,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
@ -553,7 +707,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
@ -568,38 +723,65 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
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)]
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)]
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)]
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)]
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)]
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)]
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)]
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)]
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)]
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)]
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)]
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)]
pub fn to_i8(&self) -> Result<i8, Error> {
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)),
}
}
@ -607,7 +789,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_u8(&self) -> Result<u8, Error> {
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)),
}
}
@ -615,7 +799,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_i16(&self) -> Result<i16, Error> {
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)),
}
}
@ -623,7 +809,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_u16(&self) -> Result<u16, Error> {
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)),
}
}
@ -631,7 +819,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_i32(&self) -> Result<i32, Error> {
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)),
}
}
@ -639,7 +829,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_u32(&self) -> Result<u32, Error> {
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)),
}
}
@ -647,7 +839,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_i64(&self) -> Result<i64, Error> {
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)),
}
}
@ -655,7 +849,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_u64(&self) -> Result<u64, Error> {
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)),
}
}
@ -663,7 +859,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_i128(&self) -> Result<i128, Error> {
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)),
}
}
@ -671,7 +869,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_u128(&self) -> Result<u128, Error> {
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)),
}
}
@ -679,7 +879,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_isize(&self) -> Result<isize, Error> {
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)),
}
}
@ -687,7 +889,9 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_usize(&self) -> Result<usize, Error> {
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)),
}
}
@ -732,7 +936,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
@ -773,7 +978,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
@ -814,7 +1020,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
@ -835,7 +1042,7 @@ impl<N: NestedValue> Value<N> {
match arity {
Some(expected) if r.arity() == expected => Some(r),
Some(_other) => None,
None => Some(r)
None => Some(r),
}
} else {
None
@ -856,7 +1063,7 @@ impl<N: NestedValue> Value<N> {
match arity {
Some(expected) if r.arity() == expected => Some(r),
Some(_other) => None,
None => Some(r)
None => Some(r),
}
} else {
None
@ -865,7 +1072,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
@ -892,18 +1100,14 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn as_simple_record(&self, label: &str, arity: Option<usize>) -> Option<&[N]> {
self.as_record(arity).and_then(|r| {
match r.label().value() {
Value::Symbol(s) if s == label => Some(r.fields()),
_ => None
}
self.as_record(arity).and_then(|r| match r.label().value() {
Value::Symbol(s) if s == label => Some(r.fields()),
_ => None,
})
}
#[inline(always)]
pub fn to_simple_record(&self, label: &str, arity: Option<usize>) ->
Result<&[N], Error>
{
pub fn to_simple_record(&self, label: &str, arity: Option<usize>) -> Result<&[N], Error> {
self.as_simple_record(label, 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),
None => match self.as_simple_record("Some", Some(1)) {
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)]
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)]
@ -988,7 +1193,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
@ -1024,7 +1230,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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)]
@ -1043,7 +1250,8 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
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> {
@ -1055,21 +1263,28 @@ impl<N: NestedValue> Value<N> {
Value::String(s) => Value::String(s.clone()),
Value::ByteString(v) => Value::ByteString(v.clone()),
Value::Symbol(v) => Value::Symbol(v.clone()),
Value::Record(r) => Value::Record(Record(r.fields_vec().iter().map(
|a| a.strip_annotations()).collect())),
Value::Sequence(v) => 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::Record(r) => Value::Record(Record(
r.fields_vec()
.iter()
.map(|a| a.strip_annotations())
.collect(),
)),
Value::Sequence(v) => {
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()),
}
}
pub fn copy_via<M: NestedValue, F, Err>(&self, f: &mut F) -> Result<Value<M>, Err>
where
F: FnMut(&N::Embedded) -> Result<Value<M>, Err>
F: FnMut(&N::Embedded) -> Result<Value<M>, Err>,
{
Ok(match self {
Value::Boolean(b) => Value::Boolean(*b),
@ -1079,35 +1294,52 @@ impl<N: NestedValue> Value<N> {
Value::String(s) => Value::String(s.clone()),
Value::ByteString(v) => Value::ByteString(v.clone()),
Value::Symbol(v) => Value::Symbol(v.clone()),
Value::Record(r) =>
Value::Record(Record(r.fields_vec().iter().map(|a| a.copy_via(f))
.collect::<Result<Vec<_>, _>>()?)),
Value::Sequence(v) => Value::Sequence(v.iter().map(|a| a.copy_via(f))
.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::Record(r) => Value::Record(Record(
r.fields_vec()
.iter()
.map(|a| a.copy_via(f))
.collect::<Result<Vec<_>, _>>()?,
)),
Value::Sequence(v) => Value::Sequence(
v.iter()
.map(|a| a.copy_via(f))
.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)?,
})
}
pub fn foreach_embedded<F, Err>(&self, f: &mut F) -> Result<(), Err>
where
F: FnMut(&N::Embedded) -> Result<(), Err>
F: FnMut(&N::Embedded) -> Result<(), Err>,
{
match self {
Value::Boolean(_) |
Value::Float(_) |
Value::Double(_) |
Value::SignedInteger(_) |
Value::String(_) |
Value::ByteString(_) |
Value::Symbol(_) => Ok(()),
Value::Record(r) => Ok(for v in r.fields_vec() { 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::Boolean(_)
| Value::Float(_)
| Value::Double(_)
| Value::SignedInteger(_)
| Value::String(_)
| Value::ByteString(_)
| Value::Symbol(_) => Ok(()),
Value::Record(r) => Ok(for v in r.fields_vec() {
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 {
k.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
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())
}
}
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())
}
}
@ -1189,12 +1427,14 @@ impl<N: NestedValue> Annotations<N> {
#[inline(always)]
pub fn to_vec(self) -> Vec<N> {
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
where
F: FnOnce(&mut Vec<N>)
F: FnOnce(&mut Vec<N>),
{
match &mut self.0 {
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>
where
F: FnMut(&N::Embedded) -> Result<Value<M>, Err>
F: FnMut(&N::Embedded) -> Result<Value<M>, Err>,
{
Ok(match &self.0 {
None =>
Annotations(None),
Some(b) =>
Annotations(Some(Box::new(b.iter().map(|a| a.copy_via(f)).collect::<Result<Vec<_>, _>>()?))),
None => Annotations(None),
Some(b) => Annotations(Some(Box::new(
b.iter()
.map(|a| a.copy_via(f))
.collect::<Result<Vec<_>, _>>()?,
))),
})
}
}
@ -1358,7 +1600,9 @@ impl<D: Embeddable> NestedValue for RcValue<D> {
#[inline(always)]
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 {
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())
}
}
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)
}
}
@ -1500,7 +1750,10 @@ impl<D: Embeddable> Debug for DummyValue<D> {
impl<D: Embeddable> DummyValue<D> {
#[inline(always)]
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)]
fn annotations(&self) -> &Annotations<Self> {
&self.0.0
&self.0 .0
}
#[inline(always)]
fn value(&self) -> &Value<Self> {
&self.0.1
&self.0 .1
}
#[inline(always)]
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
(self.0.0, self.0.1)
(self.0 .0, self.0 .1)
}
#[inline(always)]
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;
#[derive(Debug)]
pub enum 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!()
}
}
@ -103,7 +106,10 @@ impl serde::Serializer for Serializer {
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())
}
@ -115,17 +121,18 @@ impl serde::Serializer for Serializer {
Ok(Value::simple_record0(name).wrap())
}
fn serialize_unit_variant(self,
_name: &'static str,
_variant: u32,
variant_name: &'static str) ->
Result<Self::Ok>
{
fn serialize_unit_variant(
self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
) -> Result<Self::Ok> {
Ok(Value::simple_record0(variant_name).wrap())
}
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
Result<Self::Ok> where T: Serialize
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<Self::Ok>
where
T: Serialize,
{
match super::magic::receive_output_value(name, value) {
Some(v) => Ok(v),
@ -136,57 +143,78 @@ impl serde::Serializer for Serializer {
}
}
fn serialize_newtype_variant<T: ?Sized>(self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
value: &T) ->
Result<Self::Ok> where T: Serialize
fn serialize_newtype_variant<T: ?Sized>(
self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
value: &T,
) -> Result<Self::Ok>
where
T: Serialize,
{
Ok(Value::simple_record1(variant_name, to_value(value)).wrap())
}
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 })
}
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) ->
Result<Self::SerializeTupleStruct>
{
Ok(SerializeRecord { r: Value::simple_record(name, count) })
fn serialize_tuple_struct(
self,
name: &'static str,
count: usize,
) -> Result<Self::SerializeTupleStruct> {
Ok(SerializeRecord {
r: Value::simple_record(name, count),
})
}
fn serialize_tuple_variant(self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize) ->
Result<Self::SerializeTupleVariant>
{
Ok(SerializeRecord { r: Value::simple_record(variant_name, count) })
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize,
) -> Result<Self::SerializeTupleVariant> {
Ok(SerializeRecord {
r: Value::simple_record(variant_name, count),
})
}
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> {
Ok(SerializeRecord { r: Value::simple_record(name, count) })
Ok(SerializeRecord {
r: Value::simple_record(name, count),
})
}
fn serialize_struct_variant(self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize) ->
Result<Self::SerializeStructVariant>
{
Ok(SerializeRecord { r: Value::simple_record(variant_name, count) })
fn serialize_struct_variant(
self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize,
) -> Result<Self::SerializeStructVariant> {
Ok(SerializeRecord {
r: Value::simple_record(variant_name, count),
})
}
}
@ -194,12 +222,18 @@ impl serde::ser::SerializeMap for SerializeDictionary {
type Ok = IOValue;
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));
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();
self.items.insert(key, to_value(value));
Ok(())
@ -212,7 +246,8 @@ impl serde::ser::SerializeMap for SerializeDictionary {
impl SerializeRecord {
fn push<T: ?Sized>(&mut self, value: &T)
where T: Serialize
where
T: Serialize,
{
self.r.fields_vec_mut().push(to_value(value))
}
@ -227,7 +262,8 @@ impl serde::ser::SerializeStruct for SerializeRecord {
type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize
where
T: Serialize,
{
self.push(value);
Ok(())
@ -243,7 +279,8 @@ impl serde::ser::SerializeStructVariant for SerializeRecord {
type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize
where
T: Serialize,
{
self.push(value);
Ok(())
@ -258,7 +295,10 @@ impl serde::ser::SerializeTuple for SerializeRecord {
type Ok = IOValue;
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);
Ok(())
}
@ -272,7 +312,10 @@ impl serde::ser::SerializeTupleStruct for SerializeRecord {
type Ok = IOValue;
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);
Ok(())
}
@ -286,7 +329,10 @@ impl serde::ser::SerializeTupleVariant for SerializeRecord {
type Ok = IOValue;
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);
Ok(())
}
@ -300,7 +346,10 @@ impl serde::ser::SerializeSeq for SerializeSequence {
type Ok = IOValue;
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));
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()
}

View File

@ -40,17 +40,40 @@ impl Ord for SignedInteger {
match self.repr() {
SignedIntegerRepr::I128(i1) => match other.repr() {
SignedIntegerRepr::I128(i2) => i1.cmp(i2),
SignedIntegerRepr::U128(_) => if *i1 < 0 { Ordering::Less } else { Ordering::Greater },
SignedIntegerRepr::Big(n) => if n.is_negative() { Ordering::Less } else { Ordering::Greater },
SignedIntegerRepr::U128(_) => {
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::I128(_) => Ordering::Greater,
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::I128(_) |
SignedIntegerRepr::U128(_) => if n1.is_negative() { Ordering::Less } else { Ordering::Greater },
SignedIntegerRepr::I128(_) | SignedIntegerRepr::U128(_) => {
if n1.is_negative() {
Ordering::Less
} else {
Ordering::Greater
}
}
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(|_| ())
}
}
}
};
}
map_integral_type_to_signed_integer!(i8, u8);

View File

@ -14,22 +14,18 @@ impl<T> Suspendable<T> {
pub fn suspend(&mut self) -> Self {
match self {
Suspendable::Active(_) => std::mem::replace(self, Suspendable::Suspended),
Suspendable::Suspended =>
panic!("Attempt to suspend suspended Suspendable"),
Suspendable::Suspended => panic!("Attempt to suspend suspended Suspendable"),
}
}
#[inline(always)]
pub fn resume(&mut self, other: Self) {
match self {
Suspendable::Suspended =>
match other {
Suspendable::Active(_) => *self = other,
Suspendable::Suspended =>
panic!("Attempt to resume from suspended Suspendable"),
},
Suspendable::Active(_) =>
panic!("Attempt to resume non-suspended Suspendable"),
Suspendable::Suspended => match other {
Suspendable::Active(_) => *self = other,
Suspendable::Suspended => panic!("Attempt to resume from suspended Suspendable"),
},
Suspendable::Active(_) => panic!("Attempt to resume non-suspended Suspendable"),
}
}
@ -37,8 +33,7 @@ impl<T> Suspendable<T> {
pub fn take(self) -> T {
match self {
Suspendable::Active(t) => t,
Suspendable::Suspended =>
panic!("Attempt to take from suspended Suspendable"),
Suspendable::Suspended => panic!("Attempt to take from suspended Suspendable"),
}
}
}
@ -49,7 +44,7 @@ impl<T> Deref for Suspendable<T> {
fn deref(&self) -> &Self::Target {
match self {
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 {
match self {
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::is_eof_io_error;
use crate::error::syntax_error;
use crate::error::Error;
use crate::error::ExpectedKind;
use crate::error::Received;
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::DomainParse;
use crate::value::DummyValue;
@ -21,10 +25,6 @@ use crate::value::Set;
use crate::value::Token;
use crate::value::Value;
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;
@ -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 mut buf = [0; 4];
let _ = c.encode_utf8(&mut buf);
bs.extend(&buf[0 .. c.len_utf8()]);
bs.extend(&buf[0..c.len_utf8()]);
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 {
match Reader::<N>::demand_next(self, true) {
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 {
self.skip_whitespace();
match self.peek()? {
b';' => { self.skip()?; vs.push(N::new(self.comment_line()?)) }
b'@' => { self.skip()?; vs.push(self.demand_next(true)?) }
b';' => {
self.skip()?;
vs.push(N::new(self.comment_line()?))
}
b'@' => {
self.skip()?;
vs.push(self.demand_next(true)?)
}
_ => return Ok(vs),
}
}
@ -115,8 +121,14 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
loop {
self.skip_whitespace();
match self.peek()? {
b';' => { self.skip()?; self.comment_line()?; },
b'@' => { self.skip()?; Reader::<DummyValue<D>>::skip_value(self)?; },
b';' => {
self.skip()?;
self.comment_line()?;
}
b'@' => {
self.skip()?;
Reader::<DummyValue<D>>::skip_value(self)?;
}
_ => 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> {
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()?;
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 {
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()),
_ => 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> {
let mut v: u32 = 0;
for _ in 0 .. count {
for _ in 0..count {
let c = self.next_byte()?;
match (c as char).to_digit(16) {
Some(d) =>
v = v << 4 | d,
None =>
return Err(io_syntax_error("Bad hex escape")),
Some(d) => v = v << 4 | d,
None => return Err(io_syntax_error("Bad hex escape")),
}
}
Ok(v)
@ -207,7 +223,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
b'u',
|bs, r| {
let n1 = r.hexnum(4)?;
if (0xd800 ..= 0xdbff).contains(&n1) {
if (0xd800..=0xdbff).contains(&n1) {
let mut ok = true;
ok = ok && r.next_byte()? == b'\\';
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"))
} else {
let n2 = r.hexnum(4)?;
if (0xdc00 ..= 0xdfff).contains(&n2) {
if (0xdc00..=0xdfff).contains(&n2) {
let n = ((n1 - 0xd800) << 10) + (n2 - 0xdc00) + 0x10000;
append_codepoint(bs, n)
} else {
@ -225,16 +241,20 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
} else {
append_codepoint(bs, n1)
}
})?)
},
)?)
}
fn read_literal_binary<N: NestedValue>(&mut self) -> io::Result<N> {
Ok(N::new(&self.read_stringlike(
Vec::new(),
|bs, b| Ok(bs.push(b)),
b'"',
b'x',
|bs, r| Ok(bs.push(r.hexnum(2)? as u8)))?[..]))
Ok(N::new(
&self.read_stringlike(
Vec::new(),
|bs, b| Ok(bs.push(b)),
b'"',
b'x',
|bs, r| Ok(bs.push(r.hexnum(2)? as 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"))?;
return Ok(N::new(&bs[..]));
}
if c == b'-' { c = b'+'; }
if c == b'_' { c = b'/'; }
if c == b'=' { continue; }
if c == b'-' {
c = b'+';
}
if c == b'_' {
c = b'/';
}
if c == b'=' {
continue;
}
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();
loop {
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();
loop {
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> {
lazy_static! {
static ref NUMBER_RE: regex::Regex = regex::Regex::new(
r"^([-+]?\d+)(((\.\d+([eE][-+]?\d+)?)|([eE][-+]?\d+))([fF]?))?$").unwrap();
static ref NUMBER_RE: regex::Regex =
regex::Regex::new(r"^([-+]?\d+)(((\.\d+([eE][-+]?\d+)?)|([eE][-+]?\d+))([fF]?))?$")
.unwrap();
}
loop {
let c = match self.peek() {
Err(e) if is_eof_io_error(&e) => b' ',
Err(e) => return Err(e)?,
Ok(c) if (c as char).is_whitespace() => b' ',
Ok(c) => c
Ok(c) => 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)?;
return match NUMBER_RE.captures(&s) {
None => Ok(N::symbol(&s)),
Some(m) => match m.get(2) {
None => Ok(N::new(s.parse::<BigInt>().map_err(
|_| io_syntax_error(&format!(
"Invalid signed-integer number: {:?}", s)))?)),
None => Ok(N::new(s.parse::<BigInt>().map_err(|_| {
io_syntax_error(&format!("Invalid signed-integer number: {:?}", s))
})?)),
Some(_) => {
if let Some(maybe_f) = m.get(7) {
let s = m[1].to_owned() + &m[3];
if maybe_f.range().is_empty() {
Ok(N::new(s.parse::<f64>().map_err(
|_| io_syntax_error(&format!(
"Invalid double-precision number: {:?}", s)))?))
Ok(N::new(s.parse::<f64>().map_err(|_| {
io_syntax_error(&format!(
"Invalid double-precision number: {:?}",
s
))
})?))
} else {
Ok(N::new(s.parse::<f32>().map_err(
|_| io_syntax_error(&format!(
"Invalid single-precision number: {:?}", s)))?))
Ok(N::new(s.parse::<f32>().map_err(|_| {
io_syntax_error(&format!(
"Invalid single-precision number: {:?}",
s
))
})?))
}
} else {
panic!("Internal error: cannot analyze number {:?}", s)
}
}
}
}
},
};
}
c => {
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>>
Reader<'de, N> for TextReader<'de, 'src, N::Embedded, Dec, S>
impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'de>> Reader<'de, N>
for TextReader<'de, 'src, N::Embedded, Dec, S>
{
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
self.skip_whitespace();
@ -383,14 +423,18 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
}
}
b':' => {
return Err(io_syntax_error("Unexpected key/value separator between items"));
return Err(io_syntax_error(
"Unexpected key/value separator between items",
));
}
b'#' => {
self.skip()?;
match self.next_byte()? {
b'f' => N::new(false),
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'x' => match self.next_byte()? {
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)?;
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'<' => {
@ -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> {
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()?;
let mut b = B::Type::default();
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<()> {
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()?;
Ok(())
}
@ -479,7 +529,9 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
fn open_dictionary(&mut self) -> ReaderResult<()> {
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()?;
Ok(())
}
@ -495,7 +547,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
if self.next_byte()? != b':' {
return Err(syntax_error("Missing expected key/value separator"));
}
},
}
_ => (),
}
Ok(())

View File

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

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 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 {
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::U128(u) => self.write_u128(*u),
SignedIntegerRepr::Big(n) => self.write_int(n),
}
},
Value::String(s) => self.write_string(s),
Value::ByteString(bs) => self.write_bytes(bs),
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)]
pub struct TestCases {
pub tests: Map<Symbol, TestCase>
pub tests: Map<Symbol, TestCase>,
}
#[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::symbol::Symbol;
use preserves::value::de::from_value as deserialize_from_value;
use preserves::value::BinarySource;
use preserves::value::BytesBinarySource;
use preserves::value::IOBinarySource;
use preserves::value::IOValue;
use preserves::value::PackedWriter;
use preserves::value::Reader;
use preserves::value::de::from_value as deserialize_from_value;
use std::iter::Iterator;
use std::io;
use std::iter::Iterator;
mod samples;
use samples::*;
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::*;
let from_text = {
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)?;
preserves::value::TextReader::new(
&mut BytesBinarySource::new(contents.as_bytes()),
preserves::value::ViaCodec::new(preserves::value::IOValueDomainCodec))
.next_iovalue(true)?
preserves::value::ViaCodec::new(preserves::value::IOValueDomainCodec),
)
.next_iovalue(true)?
};
let from_packed = {
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);
Ok(())
}
#[test] fn compare_deserialize_text_with_packed() -> io::Result<()> {
#[test]
fn compare_deserialize_text_with_packed() -> io::Result<()> {
use io::prelude::*;
let from_text = {
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(())
}
#[test] fn read_write_read_text() -> io::Result<()> {
#[test]
fn read_write_read_text() -> io::Result<()> {
use io::prelude::*;
let from_text = {
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(())
}
#[test] fn deserialize_serialize_deserialize_text() -> io::Result<()> {
#[test]
fn deserialize_serialize_deserialize_text() -> io::Result<()> {
use io::prelude::*;
let from_text = {
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(())
}
#[test] fn run() -> io::Result<()> {
#[test]
fn run() -> io::Result<()> {
let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap();
let mut src = IOBinarySource::new(&mut fh);
let mut d = src.packed_iovalues().configured(true);
@ -112,7 +123,10 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
println!("{:?} ==> {:?}", name, case);
match case {
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!(&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
// Preserves canonical order.
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()]);
}
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()]);
}
TestCase::ParseError(_) => (),
@ -135,22 +155,33 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
TestCase::DecodeError(ref bin) => {
match decode_all(&bin[..]) {
Ok(_) => panic!("Unexpected success"),
Err(e) => if is_syntax_io_error(&e) {
// all is OK
} else {
panic!("Unexpected error {:?}", e)
Err(e) => {
if is_syntax_io_error(&e) {
// all is OK
} else {
panic!("Unexpected error {:?}", e)
}
}
}
}
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)
} else {
false
})
}
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());
}
}
}