cargo fmt
This commit is contained in:
parent
32ee76f7d8
commit
930964ca05
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(®ex)?;
|
||||
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<_>, _>>()?),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)];
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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())]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))],
|
||||
";"
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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")
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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: "",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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()?;
|
||||
|
|
|
@ -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
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()?);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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"))?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
|
|
|
@ -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<()> {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue