This is the bulk of the improvements from the `blue` branch

This commit is contained in:
Tony Garnock-Jones 2022-10-26 18:12:55 +02:00
parent 269ed2391a
commit d8f0c6aa5d
38 changed files with 2323 additions and 2067 deletions

View File

@ -64,6 +64,7 @@ Implementations of the data model, plus Syrup transfer syntax:
## Additional resources
- [Cheat sheet(s) for Preserves syntax](cheatsheet.html)
- Some [conventions for common data types](conventions.html)
- [Open questions](questions.html); see also the
[issues list]({{page.projectpages}}/issues)

View File

@ -0,0 +1 @@
(TODO)

9
_layouts/redirect.html Normal file
View File

@ -0,0 +1,9 @@
---
layout: skeleton
extra_html_headers: |
<link rel="canonical" href="{{ site.baseurl }}{{ page.redirect_target }}">
<meta http-equiv="Refresh" content="0; URL={{ site.baseurl }}{{ page.redirect_target }}">
---
<h1>Redirecting</h1>
<p>Redirecting you to <a href="{{ site.baseurl }}{{ page.redirect_target }}">{{ page.redirect_target }}</a>.</p>

11
cheatsheet.md Normal file
View File

@ -0,0 +1,11 @@
---
no_site_title: true
title: "Preserves Cheatsheets"
---
Tony Garnock-Jones <tonyg@leastfixedpoint.com>
{{ site.version_date }}. Version {{ site.version }}.
## Machine-Oriented Binary Syntax
{% include cheatsheet-binary.md %}

View File

@ -106,17 +106,10 @@ such media types following the general rules for ordering of
**Examples.**
«<mime application/octet-stream #"abcde">»
= B4 B3 04 "mime" B3 18 "application/octet-stream" B2 05 "abcde"
«<mime text/plain #"ABC">»
= B4 B3 04 "mime" B3 0A "text/plain" B2 03 "ABC" 84
«<mime application/xml #"<xhtml/>">»
= B4 B3 04 "mime" B3 0F "application/xml" B2 08 "<xhtml/>" 84
«<mime text/csv #"123,234,345">»
= B4 B3 04 "mime" B3 08 "text/csv" B2 0B "123,234,345" 84
<mime application/octet-stream #"abcde">
<mime text/plain #"ABC">
<mime application/xml #"<xhtml/>">
<mime text/csv #"123,234,345">
## Unicode normalization forms.

View File

@ -215,7 +215,7 @@ impl<'m, 'b> ModuleContext<'m, 'b> {
"'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![self.any_type(), ": _support::preserves::value::NestedValue + 'a"]])
}
pub fn extract(&mut self) -> Vec<Item> {

View File

@ -108,8 +108,8 @@ pub struct CompilerConfig {
pub fn load_schema_or_bundle(bundle: &mut Map<ModulePath, Schema>, i: &PathBuf) -> io::Result<()> {
let mut f = File::open(&i)?;
let mut src = IOBinarySource::new(&mut f);
let mut reader = src.packed_iovalues();
let blob = reader.demand_next(false)?;
let mut reader = src.packed();
let blob = reader.next_iovalue(false)?;
let language = Language::default();
if let Ok(s) = language.parse(&blob) {
@ -139,8 +139,8 @@ impl CompilerConfig {
) -> Self {
CompilerConfig {
bundle: Map::new(),
output_dir: output_dir,
fully_qualified_module_prefix: fully_qualified_module_prefix,
output_dir,
fully_qualified_module_prefix,
support_crate: "preserves_schema".to_owned(),
external_modules: Map::new(),
plugins: vec![
@ -274,9 +274,8 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
"use _support::Deserialize;",
"use _support::Parse;",
"use _support::Unparse;",
"use _support::preserves;",
"use preserves::value::Domain;",
"use preserves::value::NestedValue;",
"use _support::preserves::value::Domain;",
"use _support::preserves::value::NestedValue;",
""])));
let mut emit_items = |items: Vec<Item>| {
@ -306,18 +305,17 @@ pub fn compile(config: &CompilerConfig) -> io::Result<()> {
lines.push("".to_owned());
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"], " ",
"pub struct ", b.language_struct_name(), anglebrackets!["N: _support::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"],
"impl", anglebrackets!["N: _support::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)| {

View File

@ -175,7 +175,7 @@ fn simple_pattern_parser(
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), ");"]));
ctxt.declare_compound(body, &dest, item("preserves::value::Set::new()"));
ctxt.declare_compound(body, &dest, item("_support::preserves::value::Set::new()"));
body.push(item(seq!["for ", tmp.to_owned(),
" in ", src.to_owned(), ".value().to_set()?",
" ", codeblock(inner)]));
@ -191,7 +191,7 @@ fn simple_pattern_parser(
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()"));
ctxt.declare_compound(body, &dest, item("_support::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)]));

View File

@ -65,12 +65,12 @@ 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!["r.boundary(&", self.tracker_name.clone(), ")?;"]));
body.push(item(seq!["r.reader.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.reader.close_compound", parens![
seq!["&mut ", self.tracker_name.clone()],
seq!["&", self.item_expr]], "? ",
codeblock(inner)]))
@ -89,7 +89,7 @@ pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) {
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()?"));
ctxt.define_atom(&mut body, "_mark", item("r.reader.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)]);
@ -103,9 +103,10 @@ pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) {
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) -> ",
seq![ctxt.m.any_type(), ": _support::preserves::value::NestedValue"],
seq!["_Dec: _support::DomainDecode<", ctxt.m.any_type(), "::Embedded>"],
"_R: _support::Reader<'de>"],
seq!["(r: &mut _support::preserves::value::ConfiguredReader<'de, ", ctxt.m.any_type(), ", _Dec, _R>) -> "],
"std::result::Result<",
names::render_constructor(n), ty.generic_arg(ctxt.m),
", _support::ParseError> ",
@ -113,7 +114,7 @@ pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) {
});
body.push(item(seq![
"match ", fname, "(r) { ",
"Err(e) if e.is_conformance_error() => r.restore(&_mark)?, ",
"Err(e) if e.is_conformance_error() => r.reader.restore(&_mark)?, ",
"result => return result }"]));
}
body.push(item(seq![ctxt.err_code()]));
@ -122,10 +123,10 @@ pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) {
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()?"));
ctxt.define_atom(&mut body, "_mark", item("r.reader.mark()?"));
for e in &ps {
if need_restore {
body.push(item("r.restore(&_mark)?;"));
body.push(item("r.reader.restore(&_mark)?;"));
} else {
need_restore = true;
}
@ -141,13 +142,14 @@ pub fn gen_definition_reader(m: &mut ModuleContext, n: &str, d: &Definition) {
}
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) -> ",
"impl", anglebrackets![
"'de",
seq![ctxt.m.any_type(), ": _support::preserves::value::NestedValue"],
seq!["_Dec: _support::DomainDecode<", ctxt.m.any_type(), "::Embedded>"],
"_R: _support::Reader<'de>"], " ",
"_support::Deserialize", anglebrackets!["'de", ctxt.m.any_type(), "_Dec", "_R"], " ",
"for ", names::render_constructor(n), ty.generic_arg(ctxt.m), " ", codeblock![
seq!["fn deserialize(r: &mut _support::preserves::value::ConfiguredReader<'de, ", ctxt.m.any_type(), ", _Dec, _R>) -> ",
"std::result::Result<Self, _support::ParseError> ",
codeblock(body)]]])
});
@ -239,7 +241,7 @@ 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!["_support::preserves::value::Token::End => ", codeblock(inner)]));
},
Some(h) => {
let tails = group.into_iter().map(|(mut vs, f)| {
@ -253,7 +255,7 @@ fn read_expected_literal_seqs(
}
}
cases.extend(read_expected_literals_cases(ctxt, nested));
body.push(item(seq!["match r.next_token(true)? ", codeblock(cases)]));
body.push(item(seq!["match r.next_token()? ", codeblock(cases)]));
}
fn read_expected_literals_cases(
@ -269,7 +271,7 @@ fn read_expected_literals_cases(
let mut inner = Vec::new();
p.1(ctxt, &mut inner);
subcases.push(item(seq![
format!("preserves::value::Value::{:?}(w)", cls),
format!("_support::preserves::value::Value::{:?}(w)", cls),
match cls {
AtomClass::Boolean => match p.0.value().to_boolean().unwrap() {
true => " if *w".to_owned(),
@ -291,7 +293,7 @@ fn read_expected_literals_cases(
codeblock(inner)]));
}
subcases.push(item(seq!["_ => return ", ctxt.err_code(), "?,"]));
item(seq!["preserves::value::Token::Atom(v) => match v.value() ", codeblock(subcases)])
item(seq!["_support::preserves::value::Token::Atom(v) => match v.value() ", codeblock(subcases)])
}
ValueClass::Compound(CompoundClass::Record) => {
let mut subcases = Vec::new();
@ -300,7 +302,7 @@ fn read_expected_literals_cases(
(r.0.clone(), f)
}).collect());
item(seq![
"preserves::value::Token::Compound(preserves::value::CompoundClass::Record) => ",
"_support::preserves::value::Token::Compound(_support::preserves::value::CompoundClass::Record) => ",
codeblock(subcases)])
}
ValueClass::Compound(CompoundClass::Sequence) => {
@ -310,7 +312,7 @@ fn read_expected_literals_cases(
(s, f)
}).collect());
item(seq![
"preserves::value::Token::Compound(preserves::value::CompoundClass::Sequence) => ",
"_support::preserves::value::Token::Compound(_support::preserves::value::CompoundClass::Sequence) => ",
codeblock(subcases)])
}
ValueClass::Compound(CompoundClass::Set) => {
@ -334,7 +336,7 @@ fn read_expected_literals(
possibilities: LiteralCases,
) {
let cases = read_expected_literals_cases(ctxt, possibilities);
body.push(item(seq!["match r.next_token(true)? ", codeblock(cases)]));
body.push(item(seq!["match r.next_token()? ", codeblock(cases)]));
}
fn simple_pattern_reader(
@ -346,27 +348,27 @@ fn simple_pattern_reader(
let dest = ctxt.gentempname();
match p {
SimplePattern::Any => {
ctxt.define_atom(body, &dest, item("r.demand_next(true)?"));
ctxt.define_atom(body, &dest, item("r.demand_next()?"));
dest
},
SimplePattern::Atom { atom_kind: k } => {
let reader = match &**k {
AtomKind::Boolean => "r.next_boolean()?",
AtomKind::Float => "r.next_float()?",
AtomKind::Double => "r.next_double()?",
AtomKind::SignedInteger => "r.next_signedinteger()?",
AtomKind::String => "r.next_str()?.into_owned()",
AtomKind::ByteString => "r.next_bytestring()?.into_owned()",
AtomKind::Symbol => "r.next_symbol()?.into_owned()",
AtomKind::Boolean => "r.reader.next_boolean()?",
AtomKind::Float => "r.reader.next_float()?",
AtomKind::Double => "r.reader.next_double()?",
AtomKind::SignedInteger => "r.reader.next_signedinteger()?",
AtomKind::String => "r.reader.next_str()?.into_owned()",
AtomKind::ByteString => "r.reader.next_bytestring()?.into_owned()",
AtomKind::Symbol => "r.reader.next_symbol()?.into_owned()",
};
ctxt.define_atom(body, &dest, item(reader.to_owned()));
dest
},
SimplePattern::Embedded { .. } => {
// TODO: Is this right? If so, why doesn't it expect *two* Embedded tags in a row??
body.push(item("r.open_embedded()?;"));
ctxt.define_atom(body, &dest, item("r.demand_next(true)?.value().to_embedded()?.clone()"));
body.push(item("r.close_embedded()?;"));
body.push(item("r.reader.open_embedded()?;"));
ctxt.define_atom(body, &dest, item("r.demand_next()?.value().to_embedded()?.clone()"));
body.push(item("r.reader.close_embedded()?;"));
dest
},
SimplePattern::Lit { value } => {
@ -379,7 +381,7 @@ fn simple_pattern_reader(
let compound_dest = ctxt.gentempname();
ctxt.with_definite_mode(|ctxt| {
let boundary_tracker = BoundaryTracker::unwrap(
ctxt, body, "r.open_sequence()?;", boundary_tracker);
ctxt, body, "r.reader.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);
@ -395,13 +397,13 @@ fn simple_pattern_reader(
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.reader.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), ");"]));
ctxt.declare_compound(body, &compound_dest, item("preserves::value::Set::new()"));
ctxt.declare_compound(body, &compound_dest, item("_support::preserves::value::Set::new()"));
boundary_tracker.emit_loop(body, inner);
});
ctxt.define_atom(body, &dest, item(compound_dest));
@ -411,7 +413,7 @@ fn simple_pattern_reader(
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.reader.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);
@ -422,7 +424,7 @@ fn simple_pattern_reader(
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()"));
ctxt.declare_compound(body, &compound_dest, item("_support::preserves::value::Map::new()"));
boundary_tracker.item_expr = "_support::B::Item::DictionaryKey";
boundary_tracker.emit_loop(body, inner);
});
@ -469,7 +471,7 @@ fn pattern_reader(
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.reader.open_record()?;", "_support::B::Item::RecordLabel");
boundary_tracker.emit_boundary(body);
boundary_tracker.item_expr = "_support::B::Item::RecordField";
named_pattern_reader(ctxt, &**label, None, body);
@ -477,18 +479,18 @@ fn pattern_reader(
},
CompoundPattern::Tuple { patterns } => {
let boundary_tracker = BoundaryTracker::unwrap(
ctxt, body, "r.open_sequence()?;", boundary_tracker);
ctxt, body, "r.reader.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![
body.push(item(seq!["r.reader.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.reader.open_sequence()?;", boundary_tracker);
for p in fixed {
boundary_tracker.emit_boundary(body);
named_pattern_reader(ctxt, p, None, body);
@ -497,7 +499,7 @@ fn pattern_reader(
},
CompoundPattern::Dict { entries } => {
let boundary_tracker = BoundaryTracker::new(
ctxt, body, "r.open_dictionary()?;", "_support::B::Item::DictionaryKey");
ctxt, body, "r.reader.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();

View File

@ -53,7 +53,7 @@ impl compiler::Plugin for TypePlugin {
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>;"]
seq!["pub type _Any = _support::preserves::value::ArcValue<_Ptr>;"]
])));
}
}
@ -63,7 +63,7 @@ impl compiler::Plugin for TypePlugin {
let ty = definition_type(&m.module_path, n, d);
m.define_type(item(ty.render(m, n)));
m.define_type(item(seq![
"impl", ty.generic_decl(m), " preserves::value::Domain for ",
"impl", ty.generic_decl(m), " _support::preserves::value::Domain for ",
names::render_constructor(n), ty.generic_arg(m), " {}"]));
}
}
@ -174,9 +174,9 @@ pub fn field_type(p: &SimplePattern) -> TField {
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::Float => TField::Base("_support::preserves::value::Float".to_owned()),
AtomKind::Double => TField::Base("_support::preserves::value::Double".to_owned()),
AtomKind::SignedInteger => TField::Base("_support::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()),
@ -200,8 +200,8 @@ impl TField {
TField::Any => seq![ctxt.any_type()],
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",
TField::Set(t) => seq!["_support::preserves::value::Set<", t.render(ctxt, false), ">"],
TField::Map(k, v) => seq!["_support::preserves::value::Map",
anglebrackets![k.render(ctxt, false),
v.render(ctxt, false)]],
TField::Ref(r) =>
@ -294,7 +294,7 @@ 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"]])
seq![ctxt.any_type(), ": _support::preserves::value::NestedValue"]])
} else {
item("")
}
@ -303,9 +303,9 @@ 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 = ",
seq![ctxt.any_type(), ": _support::preserves::value::NestedValue = ",
match ctxt.schema.embedded_type {
EmbeddedTypeName::False => "preserves::value::IOValue",
EmbeddedTypeName::False => "_support::preserves::value::IOValue",
EmbeddedTypeName::Ref(_) => "_Any",
}]])
} else {

View File

@ -85,7 +85,7 @@ pub fn gen_definition_unparser(m: &mut ModuleContext, n: &str, d: &Definition) {
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(
"_support::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()))]]));
@ -144,15 +144,15 @@ fn simple_pattern_unparser(
SimplePattern::Atom { atom_kind: k } => {
match &**k {
AtomKind::Symbol =>
item(seq!["preserves::value::Value::symbol(", src.as_ref().unwrap().to_owned(), ").wrap()"]),
item(seq!["_support::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!["_support::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()"])
item(seq!["_support::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()"]),
item(seq!["_support::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 } => {
@ -169,7 +169,7 @@ fn simple_pattern_unparser(
}
SimplePattern::Setof { pattern } => {
let tmp = ctxt.gentempname();
item(seq!["preserves::value::Value::Set(",
item(seq!["_support::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()"])
@ -177,7 +177,7 @@ fn simple_pattern_unparser(
SimplePattern::Dictof { key, value } => {
let tmp_key = ctxt.gentempname();
let tmp_value = ctxt.gentempname();
item(seq!["preserves::value::Value::Dictionary(",
item(seq!["_support::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)),
@ -225,7 +225,7 @@ fn pattern_unparser(
let rtmp = ctxt.gentempname();
let mut body = Vec::new();
let init_expr = item(seq![
"preserves::value::Record(vec![",
"_support::preserves::value::Record(vec![",
named_pattern_unparser(ctxt, label, &normal_none(vc.is_struct)),
"])"]);
ctxt.declare_compound(&mut body, &rtmp, init_expr);
@ -256,13 +256,13 @@ fn pattern_unparser(
CompoundPattern::Dict { entries } => {
let dtmp = ctxt.gentempname();
let mut body = Vec::new();
ctxt.declare_compound(&mut body, &dtmp, item("preserves::value::Map::new()"));
ctxt.declare_compound(&mut body, &dtmp, item("_support::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()"]));
body.push(item(seq!["_support::preserves::value::Value::Dictionary(", dtmp, ").wrap()"]));
item(codeblock(body))
}
}
@ -283,7 +283,7 @@ fn sequenceify<'a>(
ctxt.declare_compound(&mut body, &rtmp, item("std::vec::Vec::new()"));
FieldsSink {
finish: item(seq![
"preserves::value::Value::Sequence", parens![rtmp.clone()], ".wrap()"]),
"_support::preserves::value::Value::Sequence", parens![rtmp.clone()], ".wrap()"]),
vec_expr: item(rtmp),
body: body,
}

View File

@ -1,10 +1,9 @@
pub mod schema;
use crate::support as _support;
use _support::preserves;
#[allow(non_snake_case)]
pub struct Language<N: preserves::value::NestedValue> {
pub struct Language<N: _support::preserves::value::NestedValue> {
pub LIT_15_FALSE: N /* #f */,
pub LIT_28_1: N /* 1 */,
pub LIT_0_BOOLEAN: N /* Boolean */,
@ -36,7 +35,7 @@ pub struct Language<N: preserves::value::NestedValue> {
pub LIT_20_VERSION: N /* version */
}
impl<N: preserves::value::NestedValue> Default for Language<N> {
impl<N: _support::preserves::value::NestedValue> Default for Language<N> {
fn default() -> Self {
Language {
LIT_15_FALSE: /* #f */ _support::decode_lit(&vec![128]).unwrap(),

File diff suppressed because it is too large Load Diff

View File

@ -42,8 +42,8 @@ mod tests {
let mut f = std::fs::File::open("../../../schema/schema.bin")?;
let mut src = IOBinarySource::new(&mut f);
let mut reader = src.packed_iovalues();
let schema = reader.demand_next(false)?;
let mut reader = src.packed().iovalues();
let schema = reader.demand_next()?;
let language = crate::gen::Language::default();
let parsed = Schema::parse(&language, &schema).expect("successful parse");
assert_eq!(schema, parsed.unparse(&language));

View File

@ -39,7 +39,7 @@ impl<'a, V: NestedValue> Context<'a, V> {
}
pub fn dynamic_unparse(&mut self, _module: &Vec<String>, _name: &str, _w: &V) -> Option<V> {
panic!("Not yet implemented");
todo!("Not yet implemented");
}
}

View File

@ -1,23 +1,23 @@
pub use lazy_static::lazy_static;
pub use preserves;
pub use preserves::value::DomainDecode;
pub use preserves::value::Reader;
pub use preserves::value::boundary as B;
pub mod interpret;
use preserves::value::ArcValue;
use preserves::value::ConfiguredReader;
use preserves::value::Domain;
use preserves::value::IOValue;
use preserves::value::DomainEncode;
use preserves::value::NestedValue;
use preserves::value::NoEmbeddedDomainCodec;
use preserves::value::Value;
use preserves::value::Writer;
use std::convert::From;
use std::convert::Into;
use std::convert::TryFrom;
use std::io;
use std::sync::Arc;
use std::marker::PhantomData;
use thiserror::Error;
@ -63,30 +63,50 @@ pub trait Deserialize<N: NestedValue>
where
Self: Sized
{
fn deserialize<'de, R: Reader<'de, N>>(r: &mut R) -> Result<Self, ParseError>;
fn deserialize<'de, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>(
r: &mut ConfiguredReader<'de, N, R, Dec>,
) -> Result<Self, ParseError>;
}
pub trait Serialize
{
fn serialize<W: Writer>(&self, w: &mut W) -> io::Result<()>;
}
pub struct SchemaDomainCodec<N: NestedValue>(PhantomData<N>);
impl<N: NestedValue> Default for SchemaDomainCodec<N> {
fn default() -> Self {
SchemaDomainCodec(PhantomData)
}
}
impl<N, T: Deserialize<N> + Domain> DomainDecode<T> for SchemaDomainCodec<N>
where
for<'value> N: NestedValue<Embedded = T> + 'value
{
fn decode_embedded<'de, R: Reader<'de>>(
&mut self,
r: &mut R,
read_annotations: bool,
) -> io::Result<T> {
Ok(T::deserialize(&mut r.configured::<N, T::Decode>(read_annotations, T::Decode::default()))?)
}
}
impl<N: NestedValue<Embedded = T>, T: /* Serialize + */ Domain> DomainEncode<T> for SchemaDomainCodec<N> {
fn encode_embedded<W: Writer>(
&mut self,
w: &mut W,
d: &T,
) -> io::Result<()> {
todo!()
// d.serialize(w)
}
}
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>
where
for<'a> D: TryFrom<&'a IOValue, Error = ParseError>
{
v.copy_via(&mut |d| Ok(Value::Embedded(Arc::new(D::try_from(d)?))))
}
pub fn encode_embedded<D: Domain>(
v: &ArcValue<Arc<D>>,
) -> IOValue
where
for<'a> IOValue: From<&'a D>
{
v.copy_via::<_, _, std::convert::Infallible>(
&mut |d| Ok(Value::Embedded(IOValue::from(d)))).unwrap()
preserves::value::packed::from_bytes(bs, &mut NoEmbeddedDomainCodec)
}
#[derive(Error, Debug)]
@ -100,7 +120,7 @@ pub enum ParseError {
impl From<preserves::error::Error> for ParseError {
fn from(v: preserves::error::Error) -> Self {
match v {
preserves::error::Error::Expected(_, _) =>
preserves::error::Error::Expected(_) =>
ParseError::ConformanceError("preserves::error::Error::Expected"),
_ =>
ParseError::Preserves(v),

View File

@ -4,6 +4,7 @@ use preserves::ser;
use preserves::value::BinarySource;
use preserves::value::BytesBinarySource;
use preserves::value::IOBinarySource;
use preserves::value::IOValue;
use preserves::value::IOValueDomainCodec;
use preserves::value::PackedWriter;
use preserves::value::Reader;
@ -31,7 +32,7 @@ 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()
IOBinarySource::new(&mut fh).packed().next_iovalue(true).unwrap()
}));
}
@ -39,13 +40,13 @@ 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()
IOBinarySource::new(&mut fh).packed().next_iovalue(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();
let v = IOBinarySource::new(&mut fh).packed().next_iovalue(true).unwrap();
c.bench_function("encode samples.bin", |b| b.iter_with_large_drop(
|| PackedWriter::encode_iovalue(&v).unwrap()));
}
@ -90,8 +91,8 @@ pub fn large_testdata_decoder_with_ann(c: &mut Criterion) {
fh.read_to_end(&mut bs).ok();
b.iter(|| {
let mut src = BytesBinarySource::new(&bs[..]);
let mut r = src.packed_iovalues();
while let Some(_) = r.next(true).unwrap() {}
let mut r = src.packed();
while let Some(_) = r.next::<IOValue>(true).unwrap() {}
})
});
}
@ -103,8 +104,8 @@ pub fn large_testdata_decoder_without_ann(c: &mut Criterion) {
fh.read_to_end(&mut bs).ok();
b.iter(|| {
let mut src = BytesBinarySource::new(&bs[..]);
let mut r = src.packed_iovalues();
while let Some(_) = r.next(false).unwrap() {}
let mut r = src.packed();
while let Some(_) = r.next::<IOValue>(false).unwrap() {}
})
});
}
@ -114,8 +115,8 @@ pub fn large_testdata_encoder(c: &mut Criterion) {
let mut fh = io::BufReader::new(File::open("benches/testdata.bin").unwrap());
let mut vs = vec![];
let mut src = IOBinarySource::new(&mut fh);
let mut r = src.packed_iovalues();
while let Some(v) = r.next(true).unwrap() {
let mut r = src.packed();
while let Some(v) = r.next::<IOValue>(true).unwrap() {
vs.push(v);
}
b.iter_with_large_drop(|| {

View File

@ -33,7 +33,7 @@ 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().next_iovalue(true)?;
println!("{:#?}", fruits_value);
let fruits1: Vec<Fruit> = value::de::from_value(&fruits_value)?;

View File

@ -6,14 +6,16 @@ use std::io;
use std::marker::PhantomData;
use super::value::boundary as B;
use super::value::{IOValue, IOValueDomainCodec, PackedReader, TextReader, ViaCodec};
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource};
use super::value::{PackedReader, TextReader};
use super::value::reader::Reader;
use super::value::source::BytesBinarySource;
use super::value::source::IOBinarySource;
pub use super::error::Error;
pub use super::error::{Error, ExpectedKind};
pub type Result<T> = std::result::Result<T, Error>;
pub struct Deserializer<'de, 'r, R: Reader<'de, IOValue>> {
pub struct Deserializer<'de, 'r, R: Reader<'de>> {
pub read: &'r mut R,
phantom: PhantomData<&'de ()>,
}
@ -23,12 +25,11 @@ pub fn from_bytes<'de, T>(bytes: &'de [u8]) ->
where
T: Deserialize<'de>
{
from_reader(&mut PackedReader::new(&mut BytesBinarySource::new(bytes), IOValueDomainCodec))
from_reader(&mut PackedReader::new(&mut BytesBinarySource::new(bytes)))
}
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)))
from_reader(&mut TextReader::new(&mut BytesBinarySource::new(text.as_bytes())))
}
pub fn from_read<'de, 'r, IOR: io::Read + io::Seek, T>(read: &'r mut IOR) ->
@ -36,10 +37,10 @@ pub fn from_read<'de, 'r, IOR: io::Read + io::Seek, T>(read: &'r mut IOR) ->
where
T: Deserialize<'de>
{
from_reader(&mut PackedReader::new(&mut IOBinarySource::new(read), IOValueDomainCodec))
from_reader(&mut PackedReader::new(&mut IOBinarySource::new(read)))
}
pub fn from_reader<'r, 'de, R: Reader<'de, IOValue>, T>(read: &'r mut R) ->
pub fn from_reader<'r, 'de, R: Reader<'de>, T>(read: &'r mut R) ->
Result<T>
where
T: Deserialize<'de>
@ -49,13 +50,29 @@ where
Ok(t)
}
impl<'r, 'de, R: Reader<'de, IOValue>> Deserializer<'de, 'r, R> {
impl<'r, 'de, R: Reader<'de>> Deserializer<'de, 'r, R> {
pub fn from_reader(read: &'r mut R) -> Self {
Deserializer { read, phantom: PhantomData }
}
fn new_record_boundary(&mut self) -> Result<B::Type> {
let b = B::start(B::Item::RecordLabel);
self.read.boundary(&b)?;
Ok(b)
}
fn open_simple_record(&mut self, label: &str) -> Result<B::Type> {
self.read.open_simple_record(label)?;
self.new_record_boundary()
}
fn open_record(&mut self) -> Result<B::Type> {
self.read.open_record()?;
self.new_record_boundary()
}
}
impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
impl<'r, 'de, 'a, R: Reader<'de>>
serde::de::Deserializer<'de>
for &'a mut Deserializer<'de, 'r, R>
{
@ -155,19 +172,25 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
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)?;
let result = visitor.visit_some(&mut *self)?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
} else {
Ok(visitor.visit_none::<Error>()?)
let mut b = self.open_record()?;
match self.read.next_symbol()?.as_ref() {
"None" => {
self.read.ensure_complete(b, &B::Item::RecordField)?;
visitor.visit_none::<Error>()
},
"Some" => {
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)
}
_ => Err(Error::Expected(ExpectedKind::Option)),
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
let b = self.read.open_simple_record("tuple", Some(0))?;
let b = self.open_simple_record("tuple")?;
let result = visitor.visit_unit::<Error>()?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
@ -176,7 +199,7 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
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 b = self.open_simple_record(name)?;
let result = visitor.visit_unit::<Error>()?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
@ -186,11 +209,11 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
-> Result<V::Value> where V: Visitor<'de>
{
match super::value::magic::transmit_input_value(
name, || Ok(self.read.demand_next(true)?))?
name, || Ok(self.read.next_iovalue(true)?))?
{
Some(v) => visitor.visit_u64(v),
None => {
let mut b = self.read.open_simple_record(name, Some(1))?;
let mut b = self.open_simple_record(name)?;
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)?;
@ -202,23 +225,31 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
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))
let mark = self.read.mark()?;
match self.read.open_sequence() {
Ok(()) => visitor.visit_seq(Seq::new(self, B::Type::default(), B::Item::SequenceValue)),
Err(Error::Expected(_)) => {
self.read.restore(&mark)?;
self.read.open_set()?;
visitor.visit_seq(Seq::new(self, B::Type::default(), B::Item::SetValue))
}
Err(e) => Err(e)?
}
}
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de>
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
let b = self.read.open_simple_record("tuple", Some(len))?;
let b = self.open_simple_record("tuple")?;
let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
Ok(result)
}
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V)
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 b = self.open_simple_record(name)?;
let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
@ -234,11 +265,11 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
fn deserialize_struct<V>(self,
name: &'static str,
fields: &'static [&'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 b = self.open_simple_record(name)?;
let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
@ -268,13 +299,13 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
}
}
pub struct Seq<'de, 'r, 'a, R: Reader<'de, IOValue>> {
pub struct Seq<'de, 'r, 'a, R: Reader<'de>> {
b: B::Type,
i: B::Item,
de: &'a mut Deserializer<'de, 'r, R>,
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> Seq<'de, 'r, 'a, R> {
impl<'de, 'r, 'a, R: Reader<'de>> Seq<'de, 'r, 'a, R> {
fn new(de: &'a mut Deserializer<'de, 'r, R>, b: B::Type, i: B::Item) -> Self {
Seq { b, i, de }
}
@ -296,7 +327,7 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> Seq<'de, 'r, 'a, R> {
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> SeqAccess<'de> for Seq<'de, 'r, 'a, R> {
impl<'de, 'r, 'a, R: Reader<'de>> SeqAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) ->
@ -306,7 +337,7 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> SeqAccess<'de> for Seq<'de, 'r, 'a, R
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> MapAccess<'de> for Seq<'de, 'r, 'a, R> {
impl<'de, 'r, 'a, R: Reader<'de>> MapAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) ->
@ -327,20 +358,20 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> MapAccess<'de> for Seq<'de, 'r, 'a, R
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> EnumAccess<'de> for &'a mut Deserializer<'de, 'r, R> {
impl<'de, 'r, 'a, R: Reader<'de>> EnumAccess<'de> for &'a mut Deserializer<'de, 'r, R> {
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>
{
let b = self.read.open_record(None)?;
let b = self.open_record()?;
let variant = seed.deserialize(&mut *self)?;
Ok((variant, Seq::new(self, b, B::Item::RecordField)))
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> VariantAccess<'de> for Seq<'de, 'r, 'a, R> {
impl<'de, 'r, 'a, R: Reader<'de>> VariantAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error;
fn unit_variant(mut self) -> Result<()> {

View File

@ -11,15 +11,7 @@ pub enum Error {
CannotDeserializeAny,
MissingCloseDelimiter,
MissingItem,
Expected(ExpectedKind, Received),
StreamingSerializationUnsupported,
}
#[derive(Debug)]
pub enum Received {
ReceivedSomethingElse,
ReceivedRecordWithLabel(String),
ReceivedOtherValue(String),
Expected(ExpectedKind),
}
#[derive(Debug, PartialEq)]
@ -35,16 +27,14 @@ pub enum ExpectedKind {
ByteString,
Symbol,
Record(Option<usize>),
SimpleRecord(String, Option<usize>),
Record,
SimpleRecord(String),
Sequence,
Set,
Dictionary,
Embedded,
SequenceOrSet, // Because of hacking up serde's data model: see open_sequence_or_set etc.
Option,
UnicodeScalar,
}
@ -60,7 +50,7 @@ impl From<Error> for io::Error {
match e {
Error::Io(ioe) => ioe,
Error::Message(str) => io::Error::new(io::ErrorKind::Other, str),
_ => io::Error::new(io::ErrorKind::Other, e.to_string()),
_ => io::Error::new(io::ErrorKind::Other, e),
}
}
}
@ -103,18 +93,6 @@ pub fn is_eof_error(e: &Error) -> bool {
}
}
pub fn syntax_error(s: &str) -> Error {
Error::Io(io_syntax_error(s))
}
pub fn is_syntax_error(e: &Error) -> bool {
if let Error::Io(ioe) = e {
is_syntax_io_error(ioe)
} else {
false
}
}
//---------------------------------------------------------------------------
pub fn io_eof() -> io::Error {
@ -125,10 +103,6 @@ pub fn is_eof_io_error(e: &io::Error) -> bool {
matches!(e.kind(), io::ErrorKind::UnexpectedEof)
}
pub fn io_syntax_error(s: &str) -> io::Error {
io::Error::new(io::ErrorKind::InvalidData, s)
}
pub fn is_syntax_io_error(e: &io::Error) -> bool {
matches!(e.kind(), io::ErrorKind::InvalidData)
}

View File

@ -17,7 +17,10 @@ mod dom {
Two,
}
impl Domain for Dom {}
impl Domain for Dom {
type Decode = DebugDomainCodec;
type Encode = DebugDomainCodec;
}
impl std::str::FromStr for Dom {
type Err = io::Error;
@ -235,7 +238,7 @@ mod value_tests {
#[cfg(test)]
mod decoder_tests {
use crate::value::{Value, NestedValue, BinarySource, BytesBinarySource, ConfiguredReader};
use crate::value::{Value, BinarySource, IOValue, NestedValue, BytesBinarySource, ConfiguredReader};
use crate::de::from_bytes;
use crate::error::{Error, ExpectedKind, is_eof_io_error};
@ -250,7 +253,7 @@ mod decoder_tests {
fn expect_expected<T: core::fmt::Debug>(k: ExpectedKind, r: Result<T, Error>) {
match r {
Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v),
Err(Error::Expected(k1, _)) if k1 == k => (),
Err(Error::Expected(k1)) if k1 == k => (),
Err(e) => panic!("Expected Expected({:?}), but got an error of {:?}", k, e),
}
}
@ -258,20 +261,19 @@ mod decoder_tests {
#[test] fn skip_annotations_noskip() {
let buf = &b"\x85\x92\x91"[..];
let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues());
let v = d.demand_next().unwrap();
assert_eq!(v.annotations().slice().len(), 1);
assert_eq!(v.annotations().slice()[0], Value::from(2).wrap());
let mut d = ConfiguredReader::new_default(src.packed());
let v: IOValue = d.demand_next().unwrap();
assert_eq!(v.annotations().unwrap().len(), 1);
assert_eq!(v.annotations().unwrap()[0], Value::from(2).wrap());
assert_eq!(v.value(), &Value::from(1));
}
#[test] fn skip_annotations_skip() {
let buf = &b"\x85\x92\x91"[..];
let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues());
d.set_read_annotations(false);
let v = d.demand_next().unwrap();
assert_eq!(v.annotations().slice().len(), 0);
let mut d = ConfiguredReader::new_default(src.packed()).read_annotations(false);
let v: IOValue = d.demand_next().unwrap();
assert!(v.annotations().is_none());
assert_eq!(v.value(), &Value::from(1));
}
@ -279,7 +281,7 @@ mod decoder_tests {
let buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..];
assert_eq!(buf.len(), 16);
let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues());
let mut d = ConfiguredReader::<IOValue, _, _>::new_default(src.packed());
assert_eq!(d.reader.source.index, 0);
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping"));
assert_eq!(d.reader.source.index, 8);

View File

@ -1,7 +1,7 @@
use serde::Serialize;
use super::value::IOValueDomainCodec;
use super::value::boundary as B;
use super::value::writer::{Writer, CompoundWriter};
use super::value::writer::Writer;
pub use super::error::Error;
type Result<T> = std::result::Result<T, Error>;
@ -17,22 +17,21 @@ impl<'w, W: Writer> Serializer<'w, W> {
}
}
enum SequenceVariant<W: Writer> {
Sequence(W::SeqWriter),
Record(W::RecWriter),
enum SequenceVariant {
Sequence,
Record,
}
pub struct SerializeCompound<'a, 'w, W: Writer> {
b: B::Type,
i: B::Item,
ser: &'a mut Serializer<'w, W>,
c: SequenceVariant<W>,
variant: SequenceVariant,
}
pub struct SerializeDictionary<'a, 'w, W: Writer> {
b: B::Type,
ser: &'a mut Serializer<'w, W>,
d: W::DictWriter,
}
impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
@ -91,13 +90,13 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
}
fn serialize_char(self, v: char) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(1))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("UnicodeScalar")?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
c.write_u32(v as u32)?;
c.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol("UnicodeScalar")?;
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
self.write.write_u32(v as u32)?;
self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record()?)
}
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
@ -109,37 +108,37 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
}
fn serialize_none(self) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(0))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("None")?;
c.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol("None")?;
self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record()?)
}
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")?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(&mut c, v)?;
c.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol("Some")?;
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(self.write, v)?;
self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record()?)
}
fn serialize_unit(self) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(0))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("tuple")?;
c.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol("tuple")?;
self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record()?)
}
fn serialize_unit_struct(self, 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(name)?;
c.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(name)?;
self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record()?)
}
fn serialize_unit_variant(self,
@ -148,11 +147,11 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
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)?;
c.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(variant_name)?;
self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record()?)
}
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
@ -162,13 +161,13 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
Some(v) => Ok(self.write.write(&mut IOValueDomainCodec, &v)?),
None => {
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
let mut c = self.write.start_record(Some(1))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(name)?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(&mut c, value)?;
c.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(name)?;
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(self.write, value)?;
self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record()?)
}
}
}
@ -180,72 +179,72 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
value: &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(variant_name)?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(&mut c, value)?;
c.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(variant_name)?;
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(self.write, value)?;
self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record()?)
}
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
let c = self.write.start_sequence(count)?;
Ok(SerializeCompound::seq(self, c))
fn serialize_seq(self, _count: Option<usize>) -> Result<Self::SerializeSeq> {
self.write.start_sequence()?;
Ok(SerializeCompound::seq(self))
}
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> {
let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("tuple")?;
Ok(SerializeCompound::rec(self, c))
fn serialize_tuple(self, _count: usize) -> Result<Self::SerializeTuple> {
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol("tuple")?;
Ok(SerializeCompound::rec(self))
}
fn serialize_tuple_struct(self, name: &'static str, count: usize) ->
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))
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(name)?;
Ok(SerializeCompound::rec(self))
}
fn serialize_tuple_variant(self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize) ->
_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)?;
Ok(SerializeCompound::rec(self, c))
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(variant_name)?;
Ok(SerializeCompound::rec(self))
}
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 })
fn serialize_map(self, _count: Option<usize>) -> Result<Self::SerializeMap> {
self.write.start_dictionary()?;
Ok(SerializeDictionary { b: B::Type::default(), ser: self })
}
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
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_struct(self, name: &'static str, _count: usize) -> Result<Self::SerializeStruct> {
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(name)?;
Ok(SerializeCompound::rec(self))
}
fn serialize_struct_variant(self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize) ->
_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)?;
Ok(SerializeCompound::rec(self, c))
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(variant_name)?;
Ok(SerializeCompound::rec(self))
}
}
@ -255,42 +254,42 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'w,
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)?;
self.ser.write.boundary(&self.b)?;
to_writer(self.ser.write, key)?;
self.b.shift(None);
Ok(())
}
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)?;
self.ser.write.boundary(&self.b)?;
to_writer(self.ser.write, value)?;
self.b.shift(None);
Ok(())
}
fn end(mut self) -> Result<Self::Ok> {
self.d.boundary(&self.b)?;
Ok(self.ser.write.end_dictionary(self.d)?)
fn end(self) -> Result<Self::Ok> {
self.ser.write.boundary(&self.b)?;
Ok(self.ser.write.end_dictionary()?)
}
}
impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> {
fn seq(ser: &'a mut Serializer<'w, W>, c: W::SeqWriter) -> Self {
fn seq(ser: &'a mut Serializer<'w, W>) -> Self {
SerializeCompound {
b: B::Type::default(),
i: B::Item::SequenceValue,
ser,
c: SequenceVariant::Sequence(c),
variant: SequenceVariant::Sequence,
}
}
fn rec(ser: &'a mut Serializer<'w, W>, c: W::RecWriter) -> Self {
fn rec(ser: &'a mut Serializer<'w, W>) -> Self {
SerializeCompound {
b: B::end(B::Item::RecordLabel),
i: B::Item::RecordField,
ser,
c: SequenceVariant::Record(c),
variant: SequenceVariant::Record,
}
}
@ -298,23 +297,21 @@ impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> {
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)?; }
}
self.ser.write.boundary(&self.b)?;
to_writer(self.ser.write, value)?;
self.b.shift(None);
Ok(())
}
fn complete(self) -> Result<()> {
match self.c {
SequenceVariant::Sequence(mut w) => {
w.boundary(&self.b)?;
Ok(self.ser.write.end_sequence(w)?)
match self.variant {
SequenceVariant::Sequence => {
self.ser.write.boundary(&self.b)?;
Ok(self.ser.write.end_sequence()?)
}
SequenceVariant::Record(mut w) => {
w.boundary(&self.b)?;
Ok(self.ser.write.end_record(w)?)
SequenceVariant::Record => {
self.ser.write.boundary(&self.b)?;
Ok(self.ser.write.end_record()?)
}
}
}

View File

@ -1,6 +1,6 @@
use crate::value::repr::{Float, Double};
use crate::value::{Value, NestedValue, IOValue, UnwrappedIOValue, Map};
use crate::error::{Error, ExpectedKind, Received};
use crate::value::{Value, NestedValue, IOValue, Map};
use crate::error::Error;
use serde::Deserialize;
use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
use std::iter::Iterator;
@ -11,7 +11,7 @@ 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<'de, T>(v: &'de IOValue) -> Result<T> where T: Deserialize<'de>
{
let mut de = Deserializer::from_value(v);
let t = T::deserialize(&mut de)?;
@ -22,13 +22,6 @@ impl<'de> Deserializer<'de> {
pub fn from_value(v: &'de IOValue) -> Self {
Deserializer { input: v }
}
fn check<'a, T, F>(&'a mut self, f: F, k: ExpectedKind) -> Result<T>
where F: FnOnce(&'de UnwrappedIOValue) -> Option<T>
{
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>
@ -42,7 +35,7 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
Value::Boolean(b) => visitor.visit_bool(*b),
Value::Float(Float(f)) => visitor.visit_f32(*f),
Value::Double(Double(d)) => visitor.visit_f64(*d),
Value::String(ref s) => visitor.visit_str(&s),
Value::String(s) => visitor.visit_str(&s),
Value::ByteString(_) => self.deserialize_bytes(visitor),
Value::Record(_) =>
if v.is_simple_record("tuple", Some(0)) {
@ -139,8 +132,7 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'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)
visitor.visit_borrowed_str(self.input.value().to_string()?)
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
@ -150,8 +142,7 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'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)
visitor.visit_borrowed_bytes(self.input.value().to_bytestring()?)
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
@ -328,7 +319,7 @@ impl<'a, 'de> EnumAccess<'de> for &'a mut Deserializer<'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 r = self.input.value().to_record(None)?;
let v = self.input;
self.input = r.label();
let variant = seed.deserialize(&mut *self)?;
@ -345,7 +336,7 @@ impl<'a, 'de> VariantAccess<'de> for &'a mut Deserializer<'de> {
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> where T: DeserializeSeed<'de> {
let r = self.check(|v| v.as_record(Some(1)), ExpectedKind::Record(Some(1)))?;
let r = self.input.value().to_record(Some(1))?;
self.input = &r.fields()[0];
seed.deserialize(&mut *self)
}

View File

@ -1,30 +1,23 @@
use std::io;
use super::BinarySource;
use super::BytesBinarySource;
use super::Embeddable;
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>;
pub trait Domain: Sized + std::fmt::Debug + Eq + std::hash::Hash + Ord + Clone {
type Decode: DomainDecode<Self> + Default;
type Encode: DomainEncode<Self> + Default;
}
pub trait DomainDecode<D: Embeddable> {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
pub trait DomainDecode<D: Domain> {
fn decode_embedded<'de, R: Reader<'de>>(
&mut self,
src: &'src mut S,
r: &mut R,
read_annotations: bool,
) -> io::Result<D>;
}
pub trait DomainEncode<D: Embeddable> {
pub trait DomainEncode<D: Domain> {
fn encode_embedded<W: Writer>(
&mut self,
w: &mut W,
@ -32,50 +25,110 @@ pub trait DomainEncode<D: Embeddable> {
) -> io::Result<()>;
}
impl<'a, D: Embeddable, T: DomainParse<D>> DomainParse<D> for &'a mut T {
fn parse_embedded(
impl<'a, D: Domain, T: DomainDecode<D>> DomainDecode<D> for &'a mut T {
fn decode_embedded<'de, R: Reader<'de>>(
&mut self,
v: &IOValue,
) -> io::Result<D> {
(**self).parse_embedded(v)
}
}
impl<'a, D: Embeddable, T: DomainDecode<D>> DomainDecode<D> for &'a mut T {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
&mut self,
src: &'src mut S,
r: &mut R,
read_annotations: bool,
) -> io::Result<D> {
(**self).decode_embedded(src, read_annotations)
(**self).decode_embedded(r, read_annotations)
}
}
pub struct DebugDomainEncode;
impl<D: Embeddable> DomainEncode<D> for DebugDomainEncode {
fn encode_embedded<W: Writer>(&mut self, w: &mut W, d: &D) -> io::Result<()> {
d.debug_encode(w)
impl<'a, D: Domain, T: DomainEncode<D>> DomainEncode<D> for &'a mut T {
fn encode_embedded<W: Writer>(
&mut self,
w: &mut W,
d: &D,
) -> io::Result<()> {
(**self).encode_embedded(w, d)
}
}
pub struct FromStrDomainParse;
#[derive(Default)]
pub struct DefaultDomainCodec;
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())?)
impl<D: Domain> DomainDecode<D> for DefaultDomainCodec {
fn decode_embedded<'de, R: Reader<'de>>(
&mut self,
r: &mut R,
read_annotations: bool,
) -> io::Result<D> {
D::Decode::default().decode_embedded(r, read_annotations)
}
}
impl<D: Domain> DomainEncode<D> for DefaultDomainCodec {
fn encode_embedded<W: Writer>(
&mut self,
w: &mut W,
d: &D,
) -> io::Result<()> {
D::Encode::default().encode_embedded(w, d)
}
}
#[derive(Default)]
pub struct DebugDomainCodec;
impl<Err: Into<io::Error>, D: Domain + std::str::FromStr<Err = Err>> DomainDecode<D> for DebugDomainCodec {
fn decode_embedded<'de, R: Reader<'de>>(
&mut self,
r: &mut R,
_read_annotations: bool,
) -> io::Result<D> {
r.next_str()?.parse().map_err(|e: Err| e.into())
}
}
impl<D: Domain> DomainEncode<D> for DebugDomainCodec {
fn encode_embedded<W: Writer>(
&mut self,
w: &mut W,
d: &D,
) -> io::Result<()> {
w.write_string(&format!("{:?}", d))
}
}
#[derive(Default)]
pub struct NoEmbeddedDomainCodec;
impl<D: Domain> DomainDecode<D> for NoEmbeddedDomainCodec {
fn decode_embedded<'de, R: Reader<'de>>(
&mut self,
_r: &mut R,
_read_annotations: bool,
) -> io::Result<D> {
Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))
}
}
impl<D: Domain> 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"))
}
}
#[derive(Default)]
pub struct IOValueDomainCodec;
impl Domain for IOValue {
type Decode = IOValueDomainCodec;
type Encode = IOValueDomainCodec;
}
impl DomainDecode<IOValue> for IOValueDomainCodec {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
fn decode_embedded<'de, R: Reader<'de>>(
&mut self,
src: &'src mut S,
r: &mut R,
read_annotations: bool,
) -> io::Result<IOValue> {
packed::PackedReader::new(src, IOValueDomainCodec).demand_next(read_annotations)
r.demand_next(read_annotations)
}
}
@ -88,54 +141,3 @@ impl DomainEncode<IOValue> for IOValueDomainCodec {
w.write(self, d)
}
}
pub struct NoEmbeddedDomainCodec;
impl<D: Embeddable> DomainDecode<D> for NoEmbeddedDomainCodec {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
&mut self,
_src: &'src mut S,
_read_annotations: bool,
) -> io::Result<D> {
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"))
}
}
pub struct ViaCodec<C>(C);
impl<C> ViaCodec<C> {
pub fn new(c: C) -> Self {
ViaCodec(c)
}
}
impl<D: Embeddable, C: DomainDecode<D>> DomainParse<D> for ViaCodec<C> {
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)
}
}
impl<D: Embeddable, C: DomainParse<D>> DomainDecode<D> for ViaCodec<C> {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
&mut self,
src: &'src mut S,
read_annotations: bool,
) -> io::Result<D> {
let v = src.packed(IOValueDomainCodec).demand_next(read_annotations)?;
self.0.parse_embedded(&v)
}
}

View File

@ -19,7 +19,13 @@ pub fn merge_seqs<N: NestedValue>(mut a: Vec<N>, mut b: Vec<N>) -> Option<Vec<N>
pub fn merge2<N: NestedValue>(v: N, w: N) -> Option<N> {
let (mut v_anns, v_val) = v.pieces();
let (w_anns, w_val) = w.pieces();
v_anns.modify(|anns| anns.extend(w_anns.to_vec().into_iter()));
match &mut v_anns {
None => v_anns = w_anns,
Some(vs) => match w_anns {
None => (),
Some(ws) => vs.extend(ws.into_iter()),
}
}
if v_val == w_val {
Some(N::wrap(v_anns, v_val))
} else {

View File

@ -7,6 +7,7 @@ pub mod reader;
pub mod repr;
pub mod ser;
pub mod signed_integer;
pub mod source;
pub mod suspendable;
pub mod text;
pub mod writer;
@ -14,31 +15,25 @@ pub mod merge;
pub use de::Deserializer;
pub use de::from_value;
pub use domain::Domain;
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::DefaultDomainCodec;
pub use domain::DebugDomainCodec;
pub use domain::NoEmbeddedDomainCodec;
pub use domain::ViaCodec;
pub use domain::IOValueDomainCodec;
pub use merge::merge;
pub use packed::PackedReader;
pub use packed::PackedWriter;
pub use reader::BinarySource;
pub use reader::BytesBinarySource;
pub use reader::ConfiguredReader;
pub use reader::IOBinarySource;
pub use reader::Reader;
pub use reader::Token;
pub use repr::AnnotatedValue;
pub use repr::ArcValue;
pub use repr::AtomClass;
pub use repr::CompoundClass;
pub use repr::Domain;
pub use repr::Double;
pub use repr::DummyValue;
pub use repr::Embeddable;
pub use repr::Float;
pub use repr::IOValue;
pub use repr::Map;
@ -52,8 +47,12 @@ pub use repr::Value;
pub use repr::ValueClass;
pub use ser::Serializer;
pub use ser::to_value;
pub use source::BinarySource;
pub use source::BytesBinarySource;
pub use source::IOBinarySource;
pub use text::TextReader;
pub use text::TextWriter;
pub use text::from_str;
pub use writer::Writer;
pub fn invert_map<A, B>(m: &Map<A, B>) -> Map<B, A>

View File

@ -9,24 +9,24 @@ use std::io;
use super::{BinarySource, DomainDecode, IOValue, IOValueDomainCodec, NestedValue, Reader};
pub fn from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &[u8],
decode_embedded: Dec,
pub fn from_bytes<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &'de [u8],
decode_embedded: &mut Dec,
) -> io::Result<N> {
super::BytesBinarySource::new(bs).packed(decode_embedded).demand_next(false)
super::BytesBinarySource::new(bs).packed().demand_next_domain(false, decode_embedded)
}
pub fn iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
from_bytes(bs, IOValueDomainCodec)
from_bytes(bs, &mut IOValueDomainCodec)
}
pub fn annotated_from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &[u8],
decode_embedded: Dec,
pub fn annotated_from_bytes<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &'de [u8],
decode_embedded: &mut Dec,
) -> io::Result<N> {
super::BytesBinarySource::new(bs).packed(decode_embedded).demand_next(true)
super::BytesBinarySource::new(bs).packed().demand_next_domain(true, decode_embedded)
}
pub fn annotated_iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
annotated_from_bytes(bs, IOValueDomainCodec)
annotated_from_bytes(bs, &mut IOValueDomainCodec)
}

View File

@ -1,4 +1,5 @@
use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_syntax_error};
use crate::error::{self, ExpectedKind, io_eof};
use crate::value::Domain;
use num::bigint::BigInt;
use num::traits::cast::{FromPrimitive, ToPrimitive};
@ -22,24 +23,19 @@ use super::super::{
boundary as B,
reader::{
Token,
BinarySource,
Reader,
ReaderResult,
},
repr::Annotations,
signed_integer::SignedInteger,
source::BinarySource,
};
pub struct PackedReader<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> {
pub struct PackedReader<'de, 'src, S: BinarySource<'de>> {
pub source: &'src mut S,
pub decode_embedded: Dec,
phantom: PhantomData<&'de N>,
phantom: PhantomData<&'de ()>,
}
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>>
BinarySource<'de>
for PackedReader<'de, 'src, N, Dec, S>
{
impl<'de, 'src, S: BinarySource<'de>> BinarySource<'de> for PackedReader<'de, 'src, S> {
type Mark = S::Mark;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
@ -54,58 +50,70 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
self.source.skip()
}
#[inline(always)]
fn peek(&mut self) -> io::Result<u8> {
fn peek(&mut self) -> io::Result<Option<u8>> {
self.source.peek()
}
#[inline(always)]
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>> {
self.source.readbytes(count)
}
#[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
self.source.readbytes_into(bs)
}
#[inline(always)]
fn input_position(&mut self) -> io::Result<Option<usize>> {
self.source.input_position()
}
#[inline(always)]
fn discard(&mut self, count: u64) -> io::Result<()> {
self.source.discard(count)
}
#[inline(always)]
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>> {
self.source.read_to_end()
}
}
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, S: BinarySource<'de>> PackedReader<'de, 'src, S> {
#[inline(always)]
pub fn new(source: &'src mut S, decode_embedded: Dec) -> Self {
PackedReader { source, decode_embedded, phantom: PhantomData }
pub fn new(source: &'src mut S) -> Self {
PackedReader { source, phantom: PhantomData }
}
#[inline(always)]
fn peek_noeof(&mut self) -> io::Result<u8> {
self.peek()?.ok_or_else(io_eof)
}
#[inline(always)]
fn read(&mut self) -> io::Result<u8> {
let v = self.peek()?;
let v = self.peek_noeof()?;
self.skip()?;
Ok(v)
}
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()
}
}
#[inline(always)]
fn varint(&mut self) -> io::Result<usize> {
fn varint(&mut self) -> io::Result<u64> {
let mut shift = 0;
let mut acc: usize = 0;
let mut acc: u64 = 0;
loop {
let v = self.read()?;
acc |= ((v & 0x7f) as usize) << shift;
if shift == 63 && v > 1 { Err(error::Error::Message("PackedReader length too long".to_string()))? }
acc |= ((v & 0x7f) as u64) << shift;
shift += 7;
if v & 0x80 == 0 { return Ok(acc) }
if shift >= 70 { Err(error::Error::Message("PackedReader length too long".to_string()))? }
}
}
#[inline(always)]
fn peekend(&mut self) -> io::Result<bool> {
if self.peek()? == Tag::End.into() {
if self.peek()? == Some(Tag::End.into()) {
self.skip()?;
Ok(true)
} else {
@ -116,7 +124,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
#[inline(always)]
fn peek_next_nonannotation_tag(&mut self) -> ReaderResult<Tag> {
loop {
match Tag::try_from(self.peek()?)? {
match Tag::try_from(self.peek_noeof()?)? {
Tag::Annotation => {
self.skip()?;
self.skip_value()?;
@ -133,7 +141,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
let count = self.varint()?;
Ok(self.readbytes(count)?)
} else {
Err(self.expected(k))
Err(error::Error::Expected(k))
}
}
@ -144,18 +152,22 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
self.skip()?;
Ok(())
} else {
Err(self.expected(k))
Err(error::Error::Expected(k))
}
}
#[inline(always)]
fn read_signed_integer(&mut self, count: usize) -> io::Result<SignedInteger> {
fn read_signed_integer(&mut self, count: u64) -> io::Result<SignedInteger> {
let count_u64 = count;
let count: usize = count.try_into().map_err(
|_| error::Error::Message("Signed integer too long".to_string()))?;
if count == 0 {
return Ok(SignedInteger::from(0_i128));
}
if count > 16 {
let bs = self.readbytes(count)?;
let bs = self.readbytes(count_u64)?;
if (bs[0] & 0x80) == 0 {
// Positive or zero.
let mut i = 0;
@ -213,7 +225,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(error::Error::Expected(ExpectedKind::SignedInteger))
}
}
@ -241,45 +253,62 @@ 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(error::Error::Expected(ExpectedKind::SignedInteger))
}
}
fn gather_annotations(&mut self) -> io::Result<Vec<N>> {
let mut annotations = vec![self.demand_next(true)?];
while Tag::try_from(self.peek()?)? == Tag::Annotation {
fn gather_annotations<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
dec: &mut Dec,
) -> io::Result<Vec<N>> {
let mut annotations = vec![self.demand_next_domain(true, dec)?];
while Tag::try_from(self.peek_noeof()?)? == Tag::Annotation {
self.skip()?;
annotations.push(self.demand_next(true)?);
annotations.push(self.demand_next_domain(true, dec)?);
}
Ok(annotations)
}
fn skip_annotations(&mut self) -> io::Result<()> {
self.skip_value()?;
while Tag::try_from(self.peek()?)? == Tag::Annotation {
while Tag::try_from(self.peek_noeof()?)? == Tag::Annotation {
self.skip()?;
self.skip_value()?;
}
Ok(())
}
fn next_upto_end(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
fn next_upto_end<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
dec: &mut Dec,
) -> io::Result<Option<N>> {
match self.peekend()? {
true => Ok(None),
false => Ok(Some(self.demand_next(read_annotations)?)),
false => Ok(Some(self.demand_next_domain(read_annotations, dec)?)),
}
}
#[inline(always)]
fn decodestr<'a>(&mut self, cow: Cow<'a, [u8]>) -> io::Result<Cow<'a, str>> {
match cow {
Cow::Borrowed(bs) =>
Ok(Cow::Borrowed(std::str::from_utf8(bs).map_err(|_| self.syntax_error("Invalid UTF-8"))?)),
Cow::Owned(bs) =>
Ok(Cow::Owned(String::from_utf8(bs).map_err(|_| self.syntax_error("Invalid UTF-8"))?)),
}
}
}
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>> {
match self.peek() {
Err(e) if is_eof_io_error(&e) => return Ok(None),
Err(e) => return Err(e),
Ok(_) => (),
impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S> {
fn next_domain<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
dec: &mut Dec,
) -> io::Result<Option<N>> {
match self.peek()? {
None => return Ok(None),
Some(_) => (),
}
Ok(Some(match Tag::try_from(self.read()?)? {
Tag::False => N::new(false),
@ -296,17 +325,19 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
}
Tag::Annotation => {
if read_annotations {
let mut annotations = self.gather_annotations()?;
let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces();
annotations.extend_from_slice(existing_annotations.slice());
N::wrap(Annotations::new(Some(annotations)), v)
let mut annotations = self.gather_annotations(dec)?;
let (existing_annotations, v) = self.demand_next_domain::<N, _>(read_annotations, dec)?.pieces();
if let Some(vs) = existing_annotations {
annotations.extend_from_slice(&vs[..]);
}
N::wrap(Some(Box::new(annotations)), v)
} else {
self.skip_annotations()?;
self.demand_next(read_annotations)?
self.demand_next_domain(read_annotations, dec)?
}
}
Tag::Embedded => {
Value::Embedded(self.decode_embedded.decode_embedded(self.source, read_annotations)?).wrap()
Value::Embedded(dec.decode_embedded(self, read_annotations)?).wrap()
}
Tag::SmallInteger(v) => {
// TODO: prebuild these in value.rs
@ -323,7 +354,8 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
}
Tag::String => {
let count = self.varint()?;
Value::String(decodestr(self.readbytes(count)?)?.into_owned()).wrap()
let bs = self.readbytes(count)?;
Value::String(self.decodestr(bs)?.into_owned()).wrap()
}
Tag::ByteString => {
let count = self.varint()?;
@ -331,64 +363,46 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
}
Tag::Symbol => {
let count = self.varint()?;
Value::Symbol(decodestr(self.readbytes(count)?)?.into_owned()).wrap()
let bs = self.readbytes(count)?;
Value::Symbol(self.decodestr(bs)?.into_owned()).wrap()
}
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, dec)? { vs.push(v); }
if vs.is_empty() {
return Err(io_syntax_error("Too few elements in encoded record"))
return Err(self.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, dec)? { 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, dec)? { 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)? {
while let Some(k) = self.next_upto_end(read_annotations, dec)? {
match self.next_upto_end(read_annotations, dec)? {
Some(v) => { d.insert(k, v); }
None => return Err(io_syntax_error("Missing dictionary value")),
None => return Err(self.syntax_error("Missing dictionary value")),
}
}
Value::Dictionary(d).wrap()
}
tag @ Tag::End => {
return Err(io_syntax_error(&format!("Invalid tag: {:?}", tag)));
return Err(self.syntax_error(&format!("Invalid tag: {:?}", tag)));
}
}))
}
#[inline(always)]
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> {
self.next_compound(Tag::Record, ExpectedKind::Record(arity))?;
let mut b = B::Type::default();
self.ensure_more_expected(&mut b, &B::Item::RecordLabel)?;
Ok(b)
}
#[inline(always)]
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item> {
match self.peek_next_nonannotation_tag()? {
Tag::Sequence => {
self.skip()?;
Ok(B::Item::SequenceValue)
}
Tag::Set => {
self.skip()?;
Ok(B::Item::SetValue)
}
_ =>
Err(self.expected(ExpectedKind::SequenceOrSet)),
}
fn open_record(&mut self) -> ReaderResult<()> {
self.next_compound(Tag::Record, ExpectedKind::Record)
}
#[inline(always)]
@ -438,14 +452,16 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
self.source.restore(mark)
}
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>> {
fn next_token<D: Domain, Dec: DomainDecode<D>>(
&mut self,
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<D>> {
loop {
return Ok(match Tag::try_from(self.peek()?)? {
return Ok(match Tag::try_from(self.peek_noeof()?)? {
Tag::Embedded => {
self.skip()?;
Token::Embedded(self.decode_embedded.decode_embedded(
self.source,
read_embedded_annotations)?)
Token::Embedded(decode_embedded.decode_embedded(self, read_embedded_annotations)?)
}
Tag::False |
Tag::True |
@ -457,7 +473,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
Tag::String |
Tag::ByteString |
Tag::Symbol =>
Token::Atom(self.demand_next(false)?),
Token::Atom(self.demand_next_domain(false, decode_embedded)?),
Tag::Record => { self.skip()?; Token::Compound(CompoundClass::Record) }
Tag::Sequence => { self.skip()?; Token::Compound(CompoundClass::Sequence) }
@ -475,23 +491,12 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
}
}
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)> {
match Tag::try_from(self.peek()?)? {
Tag::Annotation => {
self.skip()?;
let annotations = self.gather_annotations()?;
Ok((annotations, self.next_token(true)?))
}
_ => Ok((Vec::new(), self.next_token(true)?)),
}
}
#[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) }
_ => Err(self.expected(ExpectedKind::Boolean)),
_ => Err(error::Error::Expected(ExpectedKind::Boolean)),
}
}
@ -511,7 +516,7 @@ 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(error::Error::Expected(ExpectedKind::SignedInteger))
}
}
@ -541,7 +546,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs)) as f32)
},
_ => Err(self.expected(ExpectedKind::Float)),
_ => Err(error::Error::Expected(ExpectedKind::Float)),
}
}
@ -559,12 +564,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs)))
},
_ => Err(self.expected(ExpectedKind::Double)),
_ => Err(error::Error::Expected(ExpectedKind::Double)),
}
}
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(decodestr(self.next_atomic(Tag::String, ExpectedKind::Symbol)?)?)
let bs = self.next_atomic(Tag::String, ExpectedKind::Symbol)?;
Ok(self.decodestr(bs)?)
}
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
@ -572,16 +578,7 @@ 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)?)?)
}
}
#[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"))?)),
let bs = self.next_atomic(Tag::Symbol, ExpectedKind::Symbol)?;
Ok(self.decodestr(bs)?)
}
}

View File

@ -2,18 +2,40 @@ use num::bigint::BigInt;
use num::cast::ToPrimitive;
use std::convert::TryInto;
use std::io;
use std::ops::DerefMut;
use std::io::Write;
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;
use super::super::writer::{Writer, CompoundWriter, varint};
struct Buffers<W: io::Write> {
base: W,
stack: Vec<Vec<Vec<u8>>>,
}
pub struct PackedWriter<W: io::Write>(Suspendable<W>);
impl<W: io::Write> io::Write for Buffers<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match self.stack.last_mut() {
Some(bss) =>
bss.last_mut().expect("Internal error: PackedWriter buffer sequence underflow").write(buf),
None =>
self.base.write(buf)
}
}
fn flush(&mut self) -> io::Result<()> {
if self.stack.is_empty() {
self.base.flush()
} else {
Ok(())
}
}
}
pub struct PackedWriter<W: io::Write>(Buffers<W>);
impl PackedWriter<&mut Vec<u8>> {
#[inline(always)]
@ -32,20 +54,32 @@ impl PackedWriter<&mut Vec<u8>> {
}
}
pub fn varint<W: io::Write>(w: &mut W, mut v: u64) -> io::Result<usize> {
let mut byte_count = 0;
loop {
byte_count += 1;
if v < 128 {
w.write_all(&[v as u8])?;
return Ok(byte_count);
} else {
w.write_all(&[((v & 0x7f) + 128) as u8])?;
v >>= 7;
}
}
}
impl<W: io::Write> PackedWriter<W> {
#[inline(always)]
pub fn new(write: W) -> Self {
PackedWriter(Suspendable::new(write))
}
#[inline(always)]
pub fn w(&mut self) -> &mut W {
self.0.deref_mut()
PackedWriter(Buffers {
base: write,
stack: vec![],
})
}
#[inline(always)]
pub fn write_byte(&mut self, b: u8) -> io::Result<()> {
self.w().write_all(&[b])
self.0.write_all(&[b])
}
#[inline(always)]
@ -53,225 +87,43 @@ impl<W: io::Write> PackedWriter<W> {
let count: u8 = bs.len().try_into().unwrap();
if !(1..=16).contains(&count) { panic!("Invalid medium_integer count: {}", count) }
self.write_byte(Tag::MediumInteger(count).into())?;
self.w().write_all(bs)
self.0.write_all(bs)
}
#[inline(always)]
pub fn write_atom(&mut self, tag: Tag, bs: &[u8]) -> io::Result<()> {
self.write_byte(tag.into())?;
varint(&mut self.w(), bs.len().try_into().unwrap())?;
self.w().write_all(bs)
varint(&mut self.0, bs.len().try_into().unwrap())?;
self.0.write_all(bs)
}
#[inline(always)]
pub fn suspend(&mut self) -> Self {
PackedWriter(self.0.suspend())
}
#[inline(always)]
pub fn resume(&mut self, other: Self) {
self.0.resume(other.0)
}
}
pub struct BinaryOrderWriter(Vec<Vec<u8>>);
impl BinaryOrderWriter {
#[inline(always)]
fn new() -> Self {
BinaryOrderWriter(vec![vec![]])
}
#[inline(always)]
fn pop(&mut self) -> PackedWriter<Vec<u8>> {
PackedWriter::new(self.0.pop().unwrap())
}
#[inline(always)]
fn push(&mut self, w: PackedWriter<Vec<u8>>) {
self.0.push(w.0.take())
}
#[inline(always)]
fn items(&self) -> &Vec<Vec<u8>> {
&self.0
}
#[inline(always)]
fn items_mut(&mut self) -> &mut Vec<Vec<u8>> {
&mut self.0
}
#[inline(always)]
fn buffer(&mut self) -> &mut Vec<u8> {
self.0.last_mut().unwrap()
}
#[inline(always)]
fn finish<W: WriteWriter>(mut self, w: &mut W) -> io::Result<()> {
if !self.buffer().is_empty() { panic!("Missing final boundary()"); }
self.items_mut().pop();
self.items_mut().sort();
for bs in self.items() {
w.write_raw_bytes(&bs)?;
}
w.write_tag(Tag::End)?;
fn push(&mut self) -> io::Result<()> {
self.0.stack.push(vec![vec![]]);
Ok(())
}
}
pub trait WriteWriter: Writer {
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()>;
fn shift(&mut self) {
match self.0.stack.last_mut() {
Some(bss) => bss.push(vec![]),
None => panic!("Internal error: Preserves PackedWriter stack underflow"),
}
}
fn pop(&mut self, sorted: bool) -> io::Result<()> {
match self.0.stack.pop() {
Some(mut bss) => {
if sorted { bss.sort(); }
for bs in bss { self.0.write_all(&bs)? }
Ok(())
}
None =>
panic!("Internal error: Preserves PackedWriter stack underflow"),
}
}
#[inline(always)]
fn write_tag(&mut self, tag: Tag) -> io::Result<()> {
self.write_raw_bytes(&[tag.into()])
}
}
impl<W: io::Write> WriteWriter for PackedWriter<W> {
#[inline(always)]
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()> {
self.w().write_all(v)
}
}
impl WriteWriter for BinaryOrderWriter {
#[inline(always)]
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()> {
use io::Write;
self.buffer().write_all(v)
}
}
impl<W: io::Write> CompoundWriter for PackedWriter<W> {
#[inline(always)]
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
if let Some(B::Item::Annotation) = b.opening {
self.write_tag(Tag::Annotation)?;
}
Ok(())
}
}
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![]),
_ =>
()
}
Ok(())
}
}
macro_rules! binary_order_writer_method {
(mut $n:ident ($($argname:ident : $argty:ty),*) -> $retty:ty) =>
(#[inline(always)] fn $n (&mut self, $($argname : $argty),*) -> $retty {
(&mut PackedWriter::new(self.buffer())).$n($($argname),*)
});
}
impl Writer for BinaryOrderWriter {
type AnnWriter = PackedWriter<Vec<u8>>;
type RecWriter = PackedWriter<Vec<u8>>;
type SeqWriter = PackedWriter<Vec<u8>>;
type SetWriter = BinaryOrderWriter;
type DictWriter = BinaryOrderWriter;
type EmbeddedWriter = PackedWriter<Vec<u8>>;
#[inline(always)]
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> {
Ok(self.pop())
}
#[inline(always)]
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> {
self.push(ann);
Ok(())
}
binary_order_writer_method!(mut write_bool(v: bool) -> io::Result<()>);
binary_order_writer_method!(mut write_f32(v: f32) -> io::Result<()>);
binary_order_writer_method!(mut write_f64(v: f64) -> io::Result<()>);
binary_order_writer_method!(mut write_i8(v: i8) -> io::Result<()>);
binary_order_writer_method!(mut write_u8(v: u8) -> io::Result<()>);
binary_order_writer_method!(mut write_i16(v: i16) -> io::Result<()>);
binary_order_writer_method!(mut write_u16(v: u16) -> io::Result<()>);
binary_order_writer_method!(mut write_i32(v: i32) -> io::Result<()>);
binary_order_writer_method!(mut write_u32(v: u32) -> io::Result<()>);
binary_order_writer_method!(mut write_i64(v: i64) -> io::Result<()>);
binary_order_writer_method!(mut write_u64(v: u64) -> io::Result<()>);
binary_order_writer_method!(mut write_i128(v: i128) -> io::Result<()>);
binary_order_writer_method!(mut write_u128(v: u128) -> io::Result<()>);
binary_order_writer_method!(mut write_int(v: &BigInt) -> io::Result<()>);
binary_order_writer_method!(mut write_string(v: &str) -> io::Result<()>);
binary_order_writer_method!(mut write_bytes(v: &[u8]) -> io::Result<()>);
binary_order_writer_method!(mut write_symbol(v: &str) -> io::Result<()>);
#[inline(always)]
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> {
self.write_tag(Tag::Record)?;
Ok(self.pop())
}
#[inline(always)]
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> {
self.push(rec);
self.write_tag(Tag::End)
}
#[inline(always)]
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> {
self.write_tag(Tag::Sequence)?;
Ok(self.pop())
}
#[inline(always)]
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> {
self.push(seq);
self.write_tag(Tag::End)
}
#[inline(always)]
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> {
self.write_tag(Tag::Set)?;
Ok(BinaryOrderWriter::new())
}
#[inline(always)]
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> {
set.finish(self)
}
#[inline(always)]
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> {
self.write_tag(Tag::Dictionary)?;
Ok(BinaryOrderWriter::new())
}
#[inline(always)]
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> {
dict.finish(self)
}
#[inline(always)]
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> {
self.write_tag(Tag::Embedded)?;
Ok(self.pop())
}
#[inline(always)]
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()> {
self.push(ptr);
Ok(())
}
#[inline(always)]
fn flush(&mut self) -> io::Result<()> {
Ok(())
self.write_byte(tag.into())
}
}
@ -284,21 +136,33 @@ macro_rules! fits_in_bytes {
impl<W: io::Write> Writer for PackedWriter<W>
{
type AnnWriter = Self;
type RecWriter = Self;
type SeqWriter = Self;
type SetWriter = BinaryOrderWriter;
type DictWriter = BinaryOrderWriter;
type EmbeddedWriter = Self;
#[inline(always)]
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> {
Ok(self.suspend())
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.shift(),
_ =>
()
}
match b.opening {
Some(B::Item::Annotation) =>
self.write_tag(Tag::Annotation)?,
_ =>
()
}
Ok(())
}
#[inline(always)]
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> {
self.resume(ann);
fn start_annotations(&mut self) -> io::Result<()> {
Ok(())
}
#[inline(always)]
fn end_annotations(&mut self) -> io::Result<()> {
Ok(())
}
@ -310,13 +174,13 @@ impl<W: io::Write> Writer for PackedWriter<W>
#[inline(always)]
fn write_f32(&mut self, v: f32) -> io::Result<()> {
self.write_tag(Tag::Float)?;
self.write_raw_bytes(&u32::to_be_bytes(f32::to_bits(v)))
self.0.write_all(&u32::to_be_bytes(f32::to_bits(v)))
}
#[inline(always)]
fn write_f64(&mut self, v: f64) -> io::Result<()> {
self.write_tag(Tag::Double)?;
self.write_raw_bytes(&u64::to_be_bytes(f64::to_bits(v)))
self.0.write_all(&u64::to_be_bytes(f64::to_bits(v)))
}
#[inline(always)]
@ -437,9 +301,9 @@ impl<W: io::Write> Writer for PackedWriter<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)?;
varint(&mut self.0, 17)?;
self.write_byte(0)?;
self.write_raw_bytes(&bs)
self.0.write_all(&bs)
}
#[inline(always)]
@ -471,60 +335,61 @@ impl<W: io::Write> Writer for PackedWriter<W>
}
#[inline(always)]
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> {
fn start_record(&mut self) -> io::Result<()> {
self.write_tag(Tag::Record)?;
Ok(self.suspend())
self.push()
}
#[inline(always)]
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> {
self.resume(rec);
fn end_record(&mut self) -> io::Result<()> {
self.pop(false)?;
self.write_tag(Tag::End)
}
#[inline(always)]
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> {
fn start_sequence(&mut self) -> io::Result<()> {
self.write_tag(Tag::Sequence)?;
Ok(self.suspend())
self.push()
}
#[inline(always)]
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> {
self.resume(seq);
fn end_sequence(&mut self) -> io::Result<()> {
self.pop(false)?;
self.write_tag(Tag::End)
}
#[inline(always)]
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> {
fn start_set(&mut self) -> io::Result<()> {
self.write_tag(Tag::Set)?;
Ok(BinaryOrderWriter::new())
self.push()
}
#[inline(always)]
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> {
set.finish(self)
fn end_set(&mut self) -> io::Result<()> {
self.pop(true)?;
self.write_tag(Tag::End)
}
#[inline(always)]
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> {
fn start_dictionary(&mut self) -> io::Result<()> {
self.write_tag(Tag::Dictionary)?;
Ok(BinaryOrderWriter::new())
self.push()
}
#[inline(always)]
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> {
dict.finish(self)
fn end_dictionary(&mut self) -> io::Result<()> {
self.pop(true)?;
self.write_tag(Tag::End)
}
#[inline(always)]
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> {
fn start_embedded(&mut self) -> io::Result<()> {
self.write_tag(Tag::Embedded)?;
Ok(self.suspend())
Ok(())
}
#[inline(always)]
fn end_embedded(&mut self, ann: Self::EmbeddedWriter) -> io::Result<()> {
self.resume(ann);
fn end_embedded(&mut self) -> io::Result<()> {
Ok(())
}

View File

@ -1,40 +1,48 @@
use crate::error::{self, ExpectedKind, Received, io_eof};
use crate::error::{self, ExpectedKind, io_eof};
use std::borrow::Cow;
use std::io;
use std::marker::PhantomData;
use super::CompoundClass;
use super::Domain;
use super::DomainDecode;
use super::DomainParse;
use super::Double;
use super::DummyValue;
use super::Float;
use super::IOValue;
use super::IOValueDomainCodec;
use super::PlainValue;
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>;
pub enum Token<N: NestedValue> {
Embedded(N::Embedded),
Atom(N),
#[derive(Debug)]
pub enum Token<D: Domain> {
Embedded(D),
// TODO: remove use of PlainValue here by structuring Value differently, with a ValueAtom type or similar
Atom(PlainValue<D>),
Compound(CompoundClass),
End,
}
pub trait Reader<'de, N: NestedValue> {
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>>;
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type>;
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item>;
fn open_sequence(&mut self) -> ReaderResult<()>;
fn open_set(&mut self) -> ReaderResult<()>;
fn open_dictionary(&mut self) -> ReaderResult<()>;
pub trait Reader<'de> {
fn next_domain<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>>;
fn open_record(&mut self) -> ReaderResult<()>; // followed by label, then fields
fn open_sequence(&mut self) -> ReaderResult<()>; // followed by items
fn open_set(&mut self) -> ReaderResult<()>; // followed by items
fn open_dictionary(&mut self) -> ReaderResult<()>; // followed by key/value pairs
fn boundary(&mut self, b: &B::Type) -> ReaderResult<()>;
// close_compound implies a b.shift(...) and a self.boundary(b).
// Answers true for closed, false for more.
// Implies a b.shift of None if closed or of Some(i) if not closed, plus a .boundary.
fn close_compound(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<bool>;
fn open_embedded(&mut self) -> ReaderResult<()>;
@ -44,103 +52,111 @@ pub trait Reader<'de, N: NestedValue> {
fn mark(&mut self) -> io::Result<Self::Mark>;
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>>;
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)>;
fn next_token<D: Domain, Dec: DomainDecode<D>>(
&mut self,
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<D>>;
//---------------------------------------------------------------------------
fn skip_value(&mut self) -> io::Result<()> {
// TODO efficient skipping in specific impls of this trait
let _ = self.demand_next(false)?;
let _ = self.demand_next::<DummyValue>(false)?;
Ok(())
}
fn demand_next(&mut self, read_annotations: bool) -> io::Result<N> {
fn next_iovalue(&mut self, read_annotations: bool) -> io::Result<IOValue> {
self.demand_next(read_annotations)
}
fn next<N: NestedValue>(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
self.next_domain(read_annotations, &mut <N::Embedded as Domain>::Decode::default())
}
fn demand_next<N: NestedValue>(&mut self, read_annotations: bool) -> io::Result<N> {
self.next(read_annotations)?.ok_or_else(io_eof)
}
fn demand_next_domain<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<N> {
self.next_domain(read_annotations, decode_embedded)?.ok_or_else(io_eof)
}
fn next_boolean(&mut self) -> ReaderResult<bool> {
self.demand_next(false)?.value().to_boolean()
self.next_iovalue(false)?.value().to_boolean()
}
fn next_float(&mut self) -> ReaderResult<Float> {
Ok(self.demand_next(false)?.value().to_float()?.to_owned())
Ok(self.next_iovalue(false)?.value().to_float()?.to_owned())
}
fn next_double(&mut self) -> ReaderResult<Double> {
Ok(self.demand_next(false)?.value().to_double()?.to_owned())
Ok(self.next_iovalue(false)?.value().to_double()?.to_owned())
}
fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> {
Ok(self.demand_next(false)?.value().to_signedinteger()?.to_owned())
Ok(self.next_iovalue(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.next_iovalue(false)?.value().to_i8() }
fn next_u8(&mut self) -> ReaderResult<u8> { self.next_iovalue(false)?.value().to_u8() }
fn next_i16(&mut self) -> ReaderResult<i16> { self.next_iovalue(false)?.value().to_i16() }
fn next_u16(&mut self) -> ReaderResult<u16> { self.next_iovalue(false)?.value().to_u16() }
fn next_i32(&mut self) -> ReaderResult<i32> { self.next_iovalue(false)?.value().to_i32() }
fn next_u32(&mut self) -> ReaderResult<u32> { self.next_iovalue(false)?.value().to_u32() }
fn next_i64(&mut self) -> ReaderResult<i64> { self.next_iovalue(false)?.value().to_i64() }
fn next_u64(&mut self) -> ReaderResult<u64> { self.next_iovalue(false)?.value().to_u64() }
fn next_i128(&mut self) -> ReaderResult<i128> { self.next_iovalue(false)?.value().to_i128() }
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_iovalue(false)?.value().to_u128() }
fn next_f32(&mut self) -> ReaderResult<f32> { self.next_iovalue(false)?.value().to_f32() }
fn next_f64(&mut self) -> ReaderResult<f64> { self.next_iovalue(false)?.value().to_f64() }
fn next_char(&mut self) -> ReaderResult<char> { self.next_iovalue(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.next_iovalue(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.next_iovalue(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.next_iovalue(false)?.value().to_symbol()?.to_owned()))
}
fn open_option(&mut self) -> ReaderResult<Option<B::Type>>
fn open_simple_record(&mut self, name: &str) -> ReaderResult<()>
{
let b = self.open_record(None)?;
let label: &str = &self.next_symbol()?;
match label {
"None" => {
self.ensure_complete(b, &B::Item::RecordField)?;
Ok(None)
}
"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>
{
let b = self.open_record(arity)?;
self.open_record()?;
let label: &str = &self.next_symbol()?;
if label == name {
Ok(b)
Ok(())
} 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())))
}
}
fn configured(self, read_annotations: bool) -> ConfiguredReader<'de, N, Self>
fn configured<N: NestedValue, Dec: DomainDecode<N::Embedded>>(self, read_annotations: bool, decode_embedded: Dec) -> ConfiguredReader<'de, N, Self, Dec>
where
Self: std::marker::Sized
{
ConfiguredReader {
reader: self,
read_annotations,
decode_embedded,
phantom: PhantomData,
}
}
fn iovalues(self) -> ConfiguredReader<'de, IOValue, Self, IOValueDomainCodec>
where Self: Sized
{
self.configured(true, IOValueDomainCodec)
}
fn ensure_more_expected(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<()> {
if !self.close_compound(b, i)? {
Ok(())
@ -158,17 +174,17 @@ pub trait Reader<'de, N: NestedValue> {
}
}
impl<'r, 'de, N: NestedValue, R: Reader<'de, N>> Reader<'de, N> for &'r mut R {
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
(*self).next(read_annotations)
impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R {
fn next_domain<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>> {
(*self).next_domain(read_annotations, decode_embedded)
}
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> {
(*self).open_record(arity)
}
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item> {
(*self).open_sequence_or_set()
fn open_record(&mut self) -> ReaderResult<()> {
(*self).open_record()
}
fn open_sequence(&mut self) -> ReaderResult<()> {
@ -209,210 +225,54 @@ impl<'r, 'de, N: NestedValue, R: Reader<'de, N>> Reader<'de, N> for &'r mut R {
(*self).restore(mark)
}
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>> {
(*self).next_token(read_embedded_annotations)
}
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)> {
(*self).next_annotations_and_token()
}
}
pub trait BinarySource<'de>: Sized {
type Mark;
fn mark(&mut self) -> io::Result<Self::Mark>;
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
fn skip(&mut self) -> io::Result<()>;
fn peek(&mut self) -> io::Result<u8>;
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>>;
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()>;
fn packed<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
fn next_token<D: Domain, Dec: DomainDecode<D>>(
&mut self,
decode_embedded: Dec,
) -> super::PackedReader<'de, '_, N, Dec, Self> {
super::PackedReader::new(self, decode_embedded)
}
fn packed_iovalues(&mut self) ->
super::PackedReader<'de, '_, IOValue, IOValueDomainCodec, Self>
{
self.packed(IOValueDomainCodec)
}
fn text<N: NestedValue, Dec: DomainParse<N::Embedded>>(
&mut self,
decode_embedded: Dec,
) -> super::TextReader<'de, '_, N::Embedded, Dec, Self> {
super::TextReader::new(self, decode_embedded)
}
fn text_iovalues(&mut self) ->
super::TextReader<'de, '_, IOValue, ViaCodec<IOValueDomainCodec>, Self>
{
self.text::<IOValue, _>(ViaCodec::new(IOValueDomainCodec))
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<D>> {
(*self).next_token(read_embedded_annotations, decode_embedded)
}
}
pub struct IOBinarySource<R: io::Read + io::Seek> {
pub read: R,
pub buf: Option<u8>,
}
impl<R: io::Read + io::Seek> IOBinarySource<R> {
#[inline(always)]
pub fn new(read: R) -> Self {
IOBinarySource { read, buf: None }
}
}
impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
type Mark = u64;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.read.stream_position()? - (if self.buf.is_some() { 1 } else { 0 }))
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.read.seek(io::SeekFrom::Start(*mark))?;
self.buf = None;
Ok(())
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.buf.is_none() { unreachable!(); }
self.buf = None;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<u8> {
match self.buf {
Some(b) => Ok(b),
None => {
let b = &mut [0];
match self.read.read(b)? {
0 => Err(io_eof()),
1 => {
self.buf = Some(b[0]);
Ok(b[0])
}
_ => unreachable!(),
}
}
}
}
#[inline(always)]
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
if self.buf.is_some() { unreachable!(); }
let mut bs = vec![0; count];
self.read.read_exact(&mut bs)?;
Ok(Cow::Owned(bs))
}
#[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
if self.buf.is_some() { unreachable!(); }
self.read.read_exact(bs)
}
}
pub struct BytesBinarySource<'de> {
pub bytes: &'de [u8],
pub index: usize,
}
impl<'de> BytesBinarySource<'de> {
#[inline(always)]
pub fn new(bytes: &'de [u8]) -> Self {
BytesBinarySource { bytes, index: 0 }
}
}
impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
type Mark = usize;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.index)
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.index = *mark;
Ok(())
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.index >= self.bytes.len() { unreachable!(); }
self.index += 1;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<u8> {
if self.index >= self.bytes.len() {
Err(io_eof())
} else {
Ok(self.bytes[self.index])
}
}
#[inline(always)]
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
if self.index + count > self.bytes.len() {
Err(io_eof())
} else {
let bs = &self.bytes[self.index..self.index+count];
self.index += count;
Ok(Cow::Borrowed(bs))
}
}
#[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
let count = bs.len();
if self.index + count > self.bytes.len() {
Err(io_eof())
} else {
bs.copy_from_slice(&self.bytes[self.index..self.index+count]);
self.index += count;
Ok(())
}
}
}
pub struct ConfiguredReader<'de, N: NestedValue, R: Reader<'de, N>> {
pub struct ConfiguredReader<'de, N: NestedValue, R: Reader<'de>, Dec: DomainDecode<N::Embedded> = <<N as NestedValue>::Embedded as Domain>::Decode> {
pub reader: R,
pub read_annotations: bool,
pub decode_embedded: Dec,
phantom: PhantomData<&'de N>,
}
impl<'de, N: NestedValue, R: Reader<'de, N>> ConfiguredReader<'de, N, R> {
pub fn new(reader: R) -> Self {
reader.configured(true)
}
pub fn set_read_annotations(&mut self, read_annotations: bool) {
self.read_annotations = read_annotations
}
pub fn demand_next(&mut self) -> io::Result<N> {
self.reader.demand_next(self.read_annotations)
impl<'de, N: NestedValue, R: Reader<'de>> ConfiguredReader<'de, N, R> {
pub fn new_default(reader: R) -> Self {
reader.configured(true, <<N as NestedValue>::Embedded as Domain>::Decode::default())
}
}
impl<'de, N: NestedValue, R: Reader<'de, N>> std::iter::Iterator for ConfiguredReader<'de, N, R> {
impl<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>> ConfiguredReader<'de, N, R, Dec> {
pub fn new(reader: R, decode_embedded: Dec) -> Self {
reader.configured(true, decode_embedded)
}
pub fn read_annotations(mut self, read_annotations: bool) -> Self {
self.read_annotations = read_annotations;
self
}
pub fn demand_next(&mut self) -> io::Result<N> {
self.reader.demand_next_domain(self.read_annotations, &mut self.decode_embedded)
}
pub fn next_token(&mut self) -> io::Result<Token<N::Embedded>> {
self.reader.next_token(self.read_annotations, &mut self.decode_embedded)
}
}
impl<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
std::iter::Iterator
for ConfiguredReader<'de, N, R, Dec>
{
type Item = io::Result<N>;
fn next(&mut self) -> Option<Self::Item> {
match self.reader.next(self.read_annotations) {
match self.reader.next_domain(self.read_annotations, &mut self.decode_embedded) {
Err(e) => Some(Err(e)),
Ok(None) => None,
Ok(Some(v)) => Some(Ok(v)),

View File

@ -10,6 +10,7 @@ use std::hash::{Hash, Hasher};
use std::io;
use std::ops::Index;
use std::ops::IndexMut;
use std::str::FromStr;
use std::string::String;
use std::sync::Arc;
use std::vec::Vec;
@ -17,32 +18,24 @@ use std::vec::Vec;
pub use std::collections::BTreeSet as Set;
pub use std::collections::BTreeMap as Map;
use super::DebugDomainEncode;
use super::FromStrDomainParse;
use super::IOValueDomainCodec;
use super::BinarySource;
use super::BytesBinarySource;
use super::DefaultDomainCodec;
use super::Domain;
use super::DomainDecode;
use super::DomainEncode;
use super::PackedWriter;
use super::Reader;
use super::TextWriter;
use super::Writer;
use super::signed_integer::SignedInteger;
use super::text;
use crate::error::{Error, ExpectedKind, Received};
use crate::error::{Error, ExpectedKind};
pub trait Domain: Sized + Debug + Eq + Hash + Ord {
fn debug_encode<W: Writer>(&self, w: &mut W) -> io::Result<()> {
w.write_string(&format!("{:?}", self))
}
}
pub type Annotations<N> = Box<Vec<N>>;
pub trait Embeddable: Domain + Clone {}
impl<T> Embeddable for T where T: Domain + Clone {}
impl<D: Domain> Domain for Arc<D> {
fn debug_encode<W: Writer>(&self, w: &mut W) -> io::Result<()> {
self.as_ref().debug_encode(w)
}
}
pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord {
type Embedded: Embeddable;
pub trait NestedValue: Sized + Debug + FromStr + Clone + Eq + Hash + Ord {
type Embedded: Domain;
#[inline(always)]
fn new<V>(v: V) -> Self where Value<Self>: From<V> {
@ -64,11 +57,11 @@ pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord {
Value::bytestring(v).wrap()
}
fn wrap(anns: Annotations<Self>, v: Value<Self>) -> Self;
fn wrap(anns: Option<Annotations<Self>>, v: Value<Self>) -> Self;
fn annotations(&self) -> &Annotations<Self>;
fn annotations(&self) -> Option<&Annotations<Self>>;
fn value(&self) -> &Value<Self>;
fn pieces(self) -> (Annotations<Self>, Value<Self>);
fn pieces(self) -> (Option<Annotations<Self>>, Value<Self>);
fn value_owned(self) -> Value<Self>;
#[inline(always)]
@ -77,28 +70,45 @@ pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord {
}
fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for ann in self.annotations().slice() {
write!(f, "@{:?} ", ann)?;
if let Some(anns) = self.annotations() {
for ann in &anns[..] {
write!(f, "@{:?} ", ann)?;
}
}
self.value().fmt(f)
}
fn strip_annotations<M: NestedValue<Embedded = Self::Embedded>>(&self) -> M {
M::wrap(Annotations::empty(), self.value().strip_annotations())
M::wrap(None, self.value().strip_annotations())
}
fn copy_via<M: NestedValue, F, Err>(&self, f: &mut F) -> Result<M, Err>
where
F: FnMut(&Self::Embedded) -> Result<Value<M>, Err>
{
Ok(M::wrap(self.annotations().copy_via(f)?, self.value().copy_via(f)?))
let v = self.value().copy_via(f)?;
match self.annotations() {
Some(anns) =>
Ok(M::wrap(Some(Box::new(anns.iter().map(|a| a.copy_via(f)).collect::<Result<Vec<M>, _>>()?)), v)),
None =>
Ok(M::wrap(None, v)),
}
}
fn as_iovalue(&self) -> io::Result<IOValue> {
let mut enc = <Self::Embedded as Domain>::Encode::default();
self.copy_via(&mut |d| {
let mut buf = vec![];
enc.encode_embedded(&mut PackedWriter::new(&mut buf), d)?;
Ok(Value::Embedded(BytesBinarySource::new(&buf).packed().next_iovalue(true)?))
})
}
fn foreach_embedded<F, Err>(&self, f: &mut F) -> Result<(), Err>
where
F: FnMut(&Self::Embedded) -> Result<(), Err>
{
match &self.annotations().0 {
match self.annotations() {
None => (),
Some(vs) => for v in vs.iter() { v.foreach_embedded(f)? },
}
@ -329,17 +339,17 @@ impl<N: NestedValue> From<Map<N, N>> for Value<N> { fn from(v: Map<N, N>) -> Sel
impl<N: NestedValue> Debug for Value<N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
TextWriter::fmt_value(f, &mut DebugDomainEncode, self).map_err(|_| std::fmt::Error)
TextWriter::fmt_value(f, &mut DefaultDomainCodec, self).map_err(|_| std::fmt::Error)
}
}
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: Domain + FromStr<Err = Err>, N: NestedValue<Embedded = D>>
FromStr for Value<N>
{
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(text::from_str::<N, _>(s, FromStrDomainParse)?.value_owned())
Ok(text::from_str::<N, _>(s, &mut DefaultDomainCodec)?.value_owned())
}
}
@ -347,7 +357,7 @@ impl<Err: Into<io::Error>, D: Embeddable + std::str::FromStr<Err = Err>, N: Nest
impl<N: NestedValue> Value<N> {
pub fn wrap(self) -> N {
N::wrap(Annotations::empty(), self)
N::wrap(None, self)
}
fn value_class(&self) -> ValueClass {
@ -385,10 +395,6 @@ impl<N: NestedValue> Value<N> {
}
}
fn expected(&self, k: ExpectedKind) -> Error {
Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", self.clone().wrap())))
}
#[inline(always)]
pub fn is_boolean(&self) -> bool {
self.as_boolean().is_some()
@ -414,7 +420,7 @@ 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(|| Error::Expected(ExpectedKind::Boolean))
}
#[inline(always)]
@ -442,7 +448,7 @@ 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(|| Error::Expected(ExpectedKind::Float))
}
#[inline(always)]
@ -490,7 +496,7 @@ 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(|| Error::Expected(ExpectedKind::Double))
}
#[inline(always)]
@ -538,7 +544,7 @@ 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(|| Error::Expected(ExpectedKind::SignedInteger))
}
#[inline(always)]
@ -553,7 +559,7 @@ 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(|| Error::Expected(ExpectedKind::SignedIntegerI128))
}
#[inline(always)]
@ -568,7 +574,7 @@ 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(|| Error::Expected(ExpectedKind::SignedIntegerU128))
}
#[inline(always)]
@ -600,7 +606,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -608,7 +614,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -616,7 +622,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -624,7 +630,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -632,7 +638,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -640,7 +646,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -648,7 +654,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -656,7 +662,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -664,7 +670,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -672,7 +678,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -680,7 +686,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -688,7 +694,7 @@ impl<N: NestedValue> Value<N> {
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))),
None => Err(self.expected(ExpectedKind::SignedInteger)),
None => Err(Error::Expected(ExpectedKind::SignedInteger)),
}
}
@ -732,7 +738,7 @@ 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(|| Error::Expected(ExpectedKind::String))
}
#[inline(always)]
@ -773,7 +779,7 @@ 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(|| Error::Expected(ExpectedKind::ByteString))
}
#[inline(always)]
@ -814,7 +820,7 @@ 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(|| Error::Expected(ExpectedKind::Symbol))
}
#[inline(always)]
@ -865,7 +871,7 @@ 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(|| Error::Expected(ExpectedKind::Record))
}
#[inline(always)]
@ -905,7 +911,7 @@ impl<N: NestedValue> Value<N> {
Result<&[N], Error>
{
self.as_simple_record(label, arity)
.ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label.to_owned(), arity)))
.ok_or_else(|| Error::Expected(ExpectedKind::SimpleRecord(label.to_owned())))
}
#[inline(always)]
@ -914,7 +920,7 @@ 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(Error::Expected(ExpectedKind::Option))
}
}
}
@ -952,7 +958,7 @@ 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(|| Error::Expected(ExpectedKind::Sequence))
}
#[inline(always)]
@ -988,7 +994,7 @@ 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(|| Error::Expected(ExpectedKind::Set))
}
#[inline(always)]
@ -1024,7 +1030,7 @@ 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(|| Error::Expected(ExpectedKind::Dictionary))
}
#[inline(always)]
@ -1043,7 +1049,7 @@ 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(|| Error::Expected(ExpectedKind::Embedded))
}
pub fn strip_annotations<M: NestedValue<Embedded = N::Embedded>>(&self) -> Value<M> {
@ -1159,83 +1165,14 @@ impl<'de> serde::Deserialize<'de> for UnwrappedIOValue {
//---------------------------------------------------------------------------
#[derive(Clone)]
pub struct Annotations<N: NestedValue>(Option<Box<Vec<N>>>);
impl<N: NestedValue> Annotations<N> {
#[inline(always)]
pub fn empty() -> Self {
Annotations(None)
}
#[inline(always)]
pub fn new(anns: Option<Vec<N>>) -> Self {
Annotations(anns.map(Box::new))
}
#[inline(always)]
pub fn maybe_slice(&self) -> Option<&[N]> {
match &self.0 {
None => None,
Some(b) => Some(&b[..]),
}
}
#[inline(always)]
pub fn slice(&self) -> &[N] {
self.maybe_slice().unwrap_or(&[])
}
#[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()
}
pub fn modify<F>(&mut self, f: F) -> &mut Self
where
F: FnOnce(&mut Vec<N>)
{
match &mut self.0 {
None => {
let mut v = Vec::new();
f(&mut v);
if !v.is_empty() {
self.0 = Some(Box::new(v));
}
}
Some(b) => {
use std::ops::DerefMut;
f(b.deref_mut());
if b.is_empty() {
self.0 = None;
}
}
}
self
}
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>
{
Ok(match &self.0 {
None =>
Annotations(None),
Some(b) =>
Annotations(Some(Box::new(b.iter().map(|a| a.copy_via(f)).collect::<Result<Vec<_>, _>>()?))),
})
}
}
/// A possibly-annotated Value, with annotations (themselves
/// possibly-annotated) in order of appearance.
#[derive(Clone)]
pub struct AnnotatedValue<N: NestedValue>(pub Annotations<N>, pub Value<N>);
pub struct AnnotatedValue<N: NestedValue>(pub Option<Annotations<N>>, pub Value<N>);
impl<N: NestedValue> AnnotatedValue<N> {
#[inline(always)]
fn new(anns: Annotations<N>, value: Value<N>) -> Self {
fn new(anns: Option<Annotations<N>>, value: Value<N>) -> Self {
AnnotatedValue(anns, value)
}
}
@ -1273,12 +1210,12 @@ impl<N: NestedValue> Ord for AnnotatedValue<N> {
//---------------------------------------------------------------------------
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct PlainValue<D: Embeddable>(AnnotatedValue<PlainValue<D>>);
pub struct PlainValue<D: Domain>(AnnotatedValue<PlainValue<D>>);
impl<D: Embeddable> PlainValue<D> {
impl<D: Domain> PlainValue<D> {
#[inline(always)]
pub fn annotations_mut(&mut self) -> &mut Annotations<Self> {
&mut (self.0).0
pub fn annotations_mut(&mut self) -> Option<&mut Annotations<Self>> {
self.0.0.as_mut()
}
#[inline(always)]
@ -1287,17 +1224,17 @@ impl<D: Embeddable> PlainValue<D> {
}
}
impl<D: Embeddable> NestedValue for PlainValue<D> {
impl<D: Domain> NestedValue for PlainValue<D> {
type Embedded = D;
#[inline(always)]
fn wrap(anns: Annotations<Self>, v: Value<Self>) -> Self {
fn wrap(anns: Option<Annotations<Self>>, v: Value<Self>) -> Self {
PlainValue(AnnotatedValue::new(anns, v))
}
#[inline(always)]
fn annotations(&self) -> &Annotations<Self> {
&(self.0).0
fn annotations(&self) -> Option<&Annotations<Self>> {
self.0.0.as_ref()
}
#[inline(always)]
@ -1306,7 +1243,7 @@ impl<D: Embeddable> NestedValue for PlainValue<D> {
}
#[inline(always)]
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
fn pieces(self) -> (Option<Annotations<Self>>, Value<Self>) {
let AnnotatedValue(anns, v) = self.0;
(anns, v)
}
@ -1317,30 +1254,37 @@ impl<D: Embeddable> NestedValue for PlainValue<D> {
}
}
impl<D: Embeddable> Debug for PlainValue<D> {
impl<D: Domain> Debug for PlainValue<D> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.debug_fmt(f)
}
}
impl<D: Domain> FromStr for PlainValue<D> {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
text::annotated_from_str(s, &mut D::Decode::default())
}
}
//---------------------------------------------------------------------------
use std::rc::Rc;
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct RcValue<D: Embeddable>(Rc<AnnotatedValue<RcValue<D>>>);
pub struct RcValue<D: Domain>(Rc<AnnotatedValue<RcValue<D>>>);
impl<D: Embeddable> NestedValue for RcValue<D> {
impl<D: Domain> NestedValue for RcValue<D> {
type Embedded = D;
#[inline(always)]
fn wrap(anns: Annotations<Self>, v: Value<Self>) -> Self {
fn wrap(anns: Option<Annotations<Self>>, v: Value<Self>) -> Self {
RcValue(Rc::new(AnnotatedValue::new(anns, v)))
}
#[inline(always)]
fn annotations(&self) -> &Annotations<Self> {
&(self.0).0
fn annotations(&self) -> Option<&Annotations<Self>> {
self.0.0.as_ref()
}
#[inline(always)]
@ -1349,7 +1293,7 @@ impl<D: Embeddable> NestedValue for RcValue<D> {
}
#[inline(always)]
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
fn pieces(self) -> (Option<Annotations<Self>>, Value<Self>) {
match Rc::try_unwrap(self.0) {
Ok(AnnotatedValue(anns, v)) => (anns, v),
Err(r) => (r.0.clone(), r.1.clone()),
@ -1362,28 +1306,35 @@ impl<D: Embeddable> NestedValue for RcValue<D> {
}
}
impl<D: Embeddable> Debug for RcValue<D> {
impl<D: Domain> Debug for RcValue<D> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.debug_fmt(f)
}
}
impl<D: Domain> FromStr for RcValue<D> {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
text::annotated_from_str(s, &mut D::Decode::default())
}
}
//---------------------------------------------------------------------------
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ArcValue<D: Embeddable>(Arc<AnnotatedValue<ArcValue<D>>>);
pub struct ArcValue<D: Domain>(Arc<AnnotatedValue<ArcValue<D>>>);
impl<D: Embeddable> NestedValue for ArcValue<D> {
impl<D: Domain> NestedValue for ArcValue<D> {
type Embedded = D;
#[inline(always)]
fn wrap(anns: Annotations<Self>, v: Value<Self>) -> Self {
fn wrap(anns: Option<Annotations<Self>>, v: Value<Self>) -> Self {
ArcValue(Arc::new(AnnotatedValue::new(anns, v)))
}
#[inline(always)]
fn annotations(&self) -> &Annotations<Self> {
&(self.0).0
fn annotations(&self) -> Option<&Annotations<Self>> {
self.0.0.as_ref()
}
#[inline(always)]
@ -1392,7 +1343,7 @@ impl<D: Embeddable> NestedValue for ArcValue<D> {
}
#[inline(always)]
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
fn pieces(self) -> (Option<Annotations<Self>>, Value<Self>) {
match Arc::try_unwrap(self.0) {
Ok(AnnotatedValue(anns, v)) => (anns, v),
Err(r) => (r.0.clone(), r.1.clone()),
@ -1408,35 +1359,36 @@ impl<D: Embeddable> NestedValue for ArcValue<D> {
}
}
impl<D: Embeddable> Debug for ArcValue<D> {
impl<D: Domain> Debug for ArcValue<D> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.debug_fmt(f)
}
}
impl<D: Domain> FromStr for ArcValue<D> {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
text::annotated_from_str(s, &mut D::Decode::default())
}
}
//---------------------------------------------------------------------------
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct IOValue(Arc<AnnotatedValue<IOValue>>);
pub type UnwrappedIOValue = Value<IOValue>;
impl Domain for IOValue {
fn debug_encode<W: Writer>(&self, w: &mut W) -> io::Result<()> {
w.write(&mut IOValueDomainCodec, self)
}
}
impl NestedValue for IOValue {
type Embedded = Self;
#[inline(always)]
fn wrap(anns: Annotations<Self>, v: Value<Self>) -> Self {
fn wrap(anns: Option<Annotations<Self>>, v: Value<Self>) -> Self {
IOValue(Arc::new(AnnotatedValue::new(anns, v)))
}
#[inline(always)]
fn annotations(&self) -> &Annotations<Self> {
&(self.0).0
fn annotations(&self) -> Option<&Annotations<Self>> {
self.0.0.as_ref()
}
#[inline(always)]
@ -1445,7 +1397,7 @@ impl NestedValue for IOValue {
}
#[inline(always)]
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
fn pieces(self) -> (Option<Annotations<Self>>, Value<Self>) {
match Arc::try_unwrap(self.0) {
Ok(AnnotatedValue(anns, v)) => (anns, v),
Err(r) => (r.0.clone(), r.1.clone()),
@ -1467,7 +1419,7 @@ impl Debug for IOValue {
}
}
impl std::str::FromStr for IOValue {
impl FromStr for IOValue {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
text::annotated_iovalue_from_str(s)
@ -1489,47 +1441,79 @@ impl<'de> serde::Deserialize<'de> for IOValue {
//---------------------------------------------------------------------------
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct DummyValue<D: Embeddable>(AnnotatedValue<DummyValue<D>>);
pub struct DummyValue;
impl<D: Embeddable> Debug for DummyValue<D> {
impl Default for DummyValue {
fn default() -> Self {
DummyValue
}
}
impl Domain for DummyValue {
type Decode = DummyValue;
type Encode = DummyValue;
}
impl DomainDecode<DummyValue> for DummyValue {
fn decode_embedded<'de, R: Reader<'de>>(
&mut self,
r: &mut R,
_read_annotations: bool,
) -> io::Result<DummyValue> {
r.skip_value()?;
Ok(DummyValue::default())
}
}
impl DomainEncode<DummyValue> for DummyValue {
fn encode_embedded<W: Writer>(
&mut self,
w: &mut W,
_d: &DummyValue,
) -> io::Result<()> {
w.write_bool(false)
}
}
impl<'de> NestedValue for DummyValue {
type Embedded = DummyValue;
#[inline(always)]
fn wrap(_anns: Option<Annotations<Self>>, _v: Value<Self>) -> Self {
DummyValue::default()
}
#[inline(always)]
fn annotations(&self) -> Option<&Annotations<Self>> {
None
}
#[inline(always)]
fn value(&self) -> &Value<Self> {
&Value::Boolean(false)
}
#[inline(always)]
fn pieces(self) -> (Option<Annotations<Self>>, Value<Self>) {
(None, Value::Boolean(false))
}
#[inline(always)]
fn value_owned(self) -> Value<Self> {
Value::Boolean(false)
}
}
impl<'de> Debug for DummyValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("<>")
}
}
impl<D: Embeddable> DummyValue<D> {
#[inline(always)]
pub fn new() -> Self {
DummyValue(AnnotatedValue::new(Annotations::empty(), Value::Boolean(false)))
}
}
impl<D: Embeddable> NestedValue for DummyValue<D> {
type Embedded = D;
#[inline(always)]
fn wrap(_anns: Annotations<Self>, _v: Value<Self>) -> Self {
DummyValue::new()
}
#[inline(always)]
fn annotations(&self) -> &Annotations<Self> {
&self.0.0
}
#[inline(always)]
fn value(&self) -> &Value<Self> {
&self.0.1
}
#[inline(always)]
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
(self.0.0, self.0.1)
}
#[inline(always)]
fn value_owned(self) -> Value<Self> {
self.0.1
impl<'de> FromStr for DummyValue {
type Err = io::Error;
fn from_str(_s: &str) -> Result<Self, Self::Err> {
Ok(DummyValue::default())
}
}

View File

@ -0,0 +1,231 @@
use crate::error::io_eof;
use std::borrow::Cow;
use std::io;
pub trait BinarySource<'de>: Sized {
type Mark;
fn mark(&mut self) -> io::Result<Self::Mark>;
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
fn input_position(&mut self) -> io::Result<Option<usize>>;
fn skip(&mut self) -> io::Result<()>;
fn peek(&mut self) -> io::Result<Option<u8>>;
fn discard(&mut self, count: u64) -> io::Result<()>;
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>>;
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()>;
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>>;
//---------------------------------------------------------------------------
fn syntax_error(&mut self, message: &str) -> io::Error {
io::Error::new(io::ErrorKind::InvalidData, SyntaxError {
position: match self.input_position() {
Ok(p) => p,
Err(_) => None,
},
message: message.to_owned(),
})
}
fn packed(&mut self) -> super::PackedReader<'de, '_, Self> {
super::PackedReader::new(self)
}
fn text(&mut self) -> super::TextReader<'de, '_, Self> {
super::TextReader::new(self)
}
}
#[derive(Debug)]
pub struct SyntaxError {
position: Option<usize>,
message: String,
}
impl std::fmt::Display for SyntaxError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "position {}: {}",
match self.position {
Some(p) => p.to_string(),
None => "??".to_string(),
},
self.message)
}
}
impl std::error::Error for SyntaxError {}
pub struct IOBinarySource<R: io::Read + io::Seek> {
pub read: R,
pub buf: Option<u8>,
}
impl<R: io::Read + io::Seek> IOBinarySource<R> {
#[inline(always)]
pub fn new(read: R) -> Self {
IOBinarySource { read, buf: None }
}
}
impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
type Mark = u64;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.read.stream_position()? - (if self.buf.is_some() { 1 } else { 0 }))
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.read.seek(io::SeekFrom::Start(*mark))?;
self.buf = None;
Ok(())
}
fn input_position(&mut self) -> io::Result<Option<usize>> {
Ok(Some(self.mark()? as usize))
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.buf.is_none() { unreachable!(); }
self.buf = None;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<Option<u8>> {
match self.buf {
Some(b) => Ok(Some(b)),
None => {
let b = &mut [0];
match self.read.read(b)? {
0 => Ok(None),
1 => {
self.buf = Some(b[0]);
Ok(Some(b[0]))
}
_ => unreachable!(),
}
}
}
}
fn discard(&mut self, mut count: u64) -> io::Result<()> {
if self.buf.is_some() { unreachable!(); }
while count > i64::MAX as u64 {
self.read.seek(io::SeekFrom::Current(i64::MAX))?;
count -= i64::MAX as u64;
}
self.read.seek(io::SeekFrom::Current(count as i64))?;
Ok(())
}
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>> {
let mut bs = vec![0; count as usize];
self.readbytes_into(&mut bs)?;
Ok(Cow::Owned(bs))
}
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
if self.buf.is_some() { unreachable!(); }
self.read.read_exact(bs)
}
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>> {
if self.buf.is_some() { unreachable!(); }
let mut bs = Vec::new();
self.read.read_to_end(&mut bs)?;
Ok(Cow::Owned(bs))
}
}
pub struct BytesBinarySource<'de> {
pub bytes: &'de [u8],
pub index: u64,
}
impl<'de> BytesBinarySource<'de> {
#[inline(always)]
pub fn new(bytes: &'de [u8]) -> Self {
BytesBinarySource { bytes, index: 0 }
}
}
impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
type Mark = u64;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.index)
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.index = *mark;
Ok(())
}
fn input_position(&mut self) -> io::Result<Option<usize>> {
Ok(Some(self.index as usize))
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.index as usize >= self.bytes.len() { unreachable!(); }
self.index += 1;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<Option<u8>> {
if self.index as usize >= self.bytes.len() {
Ok(None)
} else {
Ok(Some(self.bytes[self.index as usize]))
}
}
#[inline(always)]
fn discard(&mut self, count: u64) -> io::Result<()> {
if (self.index + count) as usize > self.bytes.len() {
Err(io_eof())
} else {
self.index += count;
Ok(())
}
}
#[inline(always)]
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>> {
let base = self.index as usize;
let limit = base + count as usize;
if limit > self.bytes.len() {
Err(io_eof())
} else {
let bs = &self.bytes[base..limit];
self.index += count;
Ok(Cow::Borrowed(bs))
}
}
#[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
let base = self.index as usize;
let count = bs.len();
let limit = base + count;
if limit > self.bytes.len() {
Err(io_eof())
} else {
bs.copy_from_slice(&self.bytes[base..limit]);
self.index += count as u64;
Ok(())
}
}
#[inline(always)]
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>> {
self.readbytes(self.bytes.len() as u64 - self.index)
}
}

View File

@ -4,30 +4,30 @@ pub mod writer;
pub use reader::TextReader;
pub use writer::TextWriter;
use crate::value::reader::BytesBinarySource;
use crate::value::source::BytesBinarySource;
use std::io;
use super::{DomainParse, IOValue, IOValueDomainCodec, NestedValue, Reader, ViaCodec};
use super::{IOValue, IOValueDomainCodec, NestedValue, Reader, DomainDecode};
pub fn from_str<N: NestedValue, Dec: DomainParse<N::Embedded>>(
s: &str,
decode_embedded: Dec,
pub fn from_str<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
s: &'de str,
decode_embedded: &mut Dec,
) -> io::Result<N> {
TextReader::new(&mut BytesBinarySource::new(s.as_bytes()), decode_embedded).demand_next(false)
TextReader::new(&mut BytesBinarySource::new(s.as_bytes())).demand_next_domain(false, decode_embedded)
}
pub fn iovalue_from_str(s: &str) -> io::Result<IOValue> {
from_str(s, ViaCodec::new(IOValueDomainCodec))
from_str(s, &mut IOValueDomainCodec)
}
pub fn annotated_from_str<N: NestedValue, Dec: DomainParse<N::Embedded>>(
s: &str,
decode_embedded: Dec,
pub fn annotated_from_str<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
s: &'de str,
decode_embedded: &mut Dec,
) -> io::Result<N> {
TextReader::new(&mut BytesBinarySource::new(s.as_bytes()), decode_embedded).demand_next(true)
TextReader::new(&mut BytesBinarySource::new(s.as_bytes())).demand_next_domain(true, decode_embedded)
}
pub fn annotated_iovalue_from_str(s: &str) -> io::Result<IOValue> {
annotated_from_str(s, ViaCodec::new(IOValueDomainCodec))
annotated_from_str(s, &mut IOValueDomainCodec)
}

View File

@ -1,18 +1,12 @@
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::io_eof;
use crate::hex;
use crate::value::CompoundClass;
use crate::value::DomainParse;
use crate::value::DummyValue;
use crate::value::Embeddable;
use crate::value::IOValue;
use crate::value::IOValueDomainCodec;
use crate::value::Domain;
use crate::value::DomainDecode;
use crate::value::Map;
use crate::value::NestedValue;
use crate::value::Reader;
@ -20,11 +14,9 @@ use crate::value::Record;
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 crate::value::source::BinarySource;
use lazy_static::lazy_static;
@ -35,52 +27,46 @@ use std::io;
use std::iter::FromIterator;
use std::marker::PhantomData;
pub struct TextReader<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>> {
pub struct TextReader<'de, 'src, S: BinarySource<'de>> {
pub source: &'src mut S,
pub dec: Dec,
phantom: PhantomData<&'de D>,
phantom: PhantomData<&'de ()>,
}
fn decode_utf8(bs: Vec<u8>) -> io::Result<String> {
Ok(String::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)
}
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()]);
Ok(())
}
impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
TextReader<'de, 'src, D, Dec, S>
impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
{
pub fn new(source: &'src mut S, dec: Dec) -> Self {
pub fn new(source: &'src mut S) -> Self {
TextReader {
source,
dec,
phantom: PhantomData,
}
}
fn peek(&mut self) -> io::Result<u8> {
fn syntax_error(&mut self, message: &str) -> io::Error {
self.source.syntax_error(message)
}
fn peek(&mut self) -> io::Result<Option<u8>> {
self.source.peek()
}
#[inline(always)]
fn peek_noeof(&mut self) -> io::Result<u8> {
self.source.peek()?.ok_or_else(io_eof)
}
fn skip(&mut self) -> io::Result<()> {
self.source.skip()
}
fn next_byte(&mut self) -> io::Result<u8> {
let b = self.source.peek()?;
let b = self.peek_noeof()?;
self.source.skip()?;
Ok(b)
}
fn skip_whitespace(&mut self) {
// Deliberately swallows errors.
while let Ok(c) = self.peek() {
while let Ok(Some(c)) = self.peek() {
match c {
b' ' | b'\t' | b'\r' | b'\n' | b',' => {
let _ = self.skip();
@ -91,21 +77,16 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
}
// TODO: This is a duplicate of fn expected in PackedReader.
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()
}
}
fn gather_annotations<N: NestedValue<Embedded = D>>(&mut self) -> ReaderResult<Vec<N>> {
fn gather_annotations<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
decode_embedded: &mut Dec,
) -> ReaderResult<Vec<N>> {
let mut vs = Vec::new();
loop {
self.skip_whitespace();
match self.peek()? {
match self.peek_noeof()? {
b';' => { self.skip()?; vs.push(N::new(self.comment_line()?)) }
b'@' => { self.skip()?; vs.push(self.demand_next(true)?) }
b'@' => { self.skip()?; vs.push(self.demand_next_domain(true, decode_embedded)?) }
_ => return Ok(vs),
}
}
@ -114,27 +95,25 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
fn skip_annotations(&mut self) -> ReaderResult<()> {
loop {
self.skip_whitespace();
match self.peek()? {
match self.peek_noeof()? {
b';' => { self.skip()?; self.comment_line()?; },
b'@' => { self.skip()?; Reader::<DummyValue<D>>::skip_value(self)?; },
b'@' => { self.skip()?; self.skip_value()?; },
_ => return Ok(()),
}
}
}
pub fn next_iovalue(&mut self, read_annotations: bool) -> io::Result<IOValue> {
let mut r = TextReader::new(self.source, ViaCodec::new(IOValueDomainCodec));
let v = r.demand_next(read_annotations)?;
Ok(v)
fn decode_utf8(&mut self, bs: Vec<u8>) -> io::Result<String> {
String::from_utf8(bs).map_err(|_| self.syntax_error("Invalid UTF-8"))
}
fn comment_line(&mut self) -> io::Result<String> {
let mut bs = Vec::new();
loop {
let b = self.peek()?;
let b = self.peek_noeof()?;
self.skip()?;
match b {
b'\r' | b'\n' => return Ok(decode_utf8(bs)?),
b'\r' | b'\n' => return Ok(self.decode_utf8(bs)?),
_ => bs.push(b),
}
}
@ -164,23 +143,23 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
hexescaper: H,
) -> io::Result<R>
where
X: Fn(&mut R, u8) -> io::Result<()>,
H: Fn(&mut R, &mut Self) -> io::Result<()>,
X: Fn(&mut Self, &mut R, u8) -> io::Result<()>,
H: Fn(&mut Self, &mut R) -> io::Result<()>,
{
loop {
match self.next_byte()? {
c if c == terminator => return Ok(seed),
b'\\' => match self.next_byte()? {
c if c == hexescape => hexescaper(&mut seed, self)?,
c if c == terminator || c == b'\\' || c == b'/' => xform_item(&mut seed, c)?,
b'b' => xform_item(&mut seed, b'\x08')?,
b'f' => xform_item(&mut seed, b'\x0c')?,
b'n' => xform_item(&mut seed, b'\x0a')?,
b'r' => xform_item(&mut seed, b'\x0d')?,
b't' => xform_item(&mut seed, b'\x09')?,
_ => return Err(io_syntax_error("Invalid escape code")),
c if c == hexescape => hexescaper(self, &mut seed)?,
c if c == terminator || c == b'\\' || c == b'/' => xform_item(self, &mut seed, c)?,
b'b' => xform_item(self, &mut seed, b'\x08')?,
b'f' => xform_item(self, &mut seed, b'\x0c')?,
b'n' => xform_item(self, &mut seed, b'\x0a')?,
b'r' => xform_item(self, &mut seed, b'\x0d')?,
b't' => xform_item(self, &mut seed, b'\x09')?,
_ => return Err(self.syntax_error("Invalid escape code")),
},
c => xform_item(&mut seed, c)?,
c => xform_item(self, &mut seed, c)?,
}
}
}
@ -193,48 +172,57 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
Some(d) =>
v = v << 4 | d,
None =>
return Err(io_syntax_error("Bad hex escape")),
return Err(self.syntax_error("Bad hex escape")),
}
}
Ok(v)
}
fn append_codepoint(&mut self, bs: &mut Vec<u8>, n: u32) -> io::Result<()> {
let c = char::from_u32(n).ok_or_else(|| self.syntax_error("Bad code point"))?;
let mut buf = [0; 4];
let _ = c.encode_utf8(&mut buf);
bs.extend(&buf[0 .. c.len_utf8()]);
Ok(())
}
fn read_string(&mut self, delimiter: u8) -> io::Result<String> {
decode_utf8(self.read_stringlike(
let raw = self.read_stringlike(
Vec::new(),
|bs, c| Ok(bs.push(c)),
|_r, bs, c| Ok(bs.push(c)),
delimiter,
b'u',
|bs, r| {
|r, bs| {
let n1 = r.hexnum(4)?;
if (0xd800 ..= 0xdbff).contains(&n1) {
let mut ok = true;
ok = ok && r.next_byte()? == b'\\';
ok = ok && r.next_byte()? == b'u';
if !ok {
Err(io_syntax_error("Missing second half of surrogate pair"))
Err(r.syntax_error("Missing second half of surrogate pair"))
} else {
let n2 = r.hexnum(4)?;
if (0xdc00 ..= 0xdfff).contains(&n2) {
let n = ((n1 - 0xd800) << 10) + (n2 - 0xdc00) + 0x10000;
append_codepoint(bs, n)
r.append_codepoint(bs, n)
} else {
Err(io_syntax_error("Bad second half of surrogate pair"))
Err(r.syntax_error("Bad second half of surrogate pair"))
}
}
} else {
append_codepoint(bs, n1)
r.append_codepoint(bs, n1)
}
})?)
})?;
self.decode_utf8(raw)
}
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)),
|_r, bs, b| Ok(bs.push(b)),
b'"',
b'x',
|bs, r| Ok(bs.push(r.hexnum(2)? as u8)))?[..]))
|r, bs| Ok(bs.push(r.hexnum(2)? as u8)))?[..]))
}
fn read_hex_binary(&mut self) -> io::Result<Vec<u8>> {
@ -247,7 +235,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
let c2 = self.next_byte()? as char;
if !(c1.is_digit(16) && c2.is_digit(16)) {
return Err(io_syntax_error("Invalid hex binary"));
return Err(self.syntax_error("Invalid hex binary"));
}
s.push(c1);
s.push(c2);
@ -260,8 +248,8 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
self.skip_whitespace();
let mut c = self.next_byte()?;
if c == b']' {
let bs = base64::decode_config(&decode_utf8(bs)?, base64::STANDARD_NO_PAD)
.map_err(|_| io_syntax_error("Invalid base64 character"))?;
let bs = base64::decode_config(&self.decode_utf8(bs)?, base64::STANDARD_NO_PAD)
.map_err(|_| self.syntax_error("Invalid base64 character"))?;
return Ok(N::new(&bs[..]));
}
if c == b'-' { c = b'+'; }
@ -271,32 +259,41 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
}
fn upto<N: NestedValue<Embedded = D>>(&mut self, delimiter: u8, read_annotations: bool) -> io::Result<Vec<N>> {
fn upto<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
delimiter: u8,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Vec<N>> {
let mut vs = Vec::new();
loop {
self.skip_whitespace();
if self.peek()? == delimiter {
if self.peek()? == Some(delimiter) {
self.skip()?;
return Ok(vs);
}
vs.push(Reader::<N>::demand_next(self, read_annotations)?);
vs.push(self.demand_next_domain(read_annotations, decode_embedded)?);
}
}
fn read_dictionary<N: NestedValue<Embedded = D>>(&mut self, read_annotations: bool) -> io::Result<N> {
fn read_dictionary<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<N> {
let mut d = Map::new();
loop {
self.skip_whitespace();
if self.peek()? == b'}' {
if self.peek_noeof()? == b'}' {
self.skip()?;
return Ok(N::new(d));
}
let k = Reader::<N>::demand_next(self, read_annotations)?;
let k = self.demand_next_domain(read_annotations, decode_embedded)?;
self.skip_whitespace();
if self.next_byte()? != b':' {
return Err(io_syntax_error("Missing expected key/value separator"));
return Err(self.syntax_error("Missing expected key/value separator"));
}
let v = Reader::<N>::demand_next(self, read_annotations)?;
let v = self.demand_next_domain(read_annotations, decode_embedded)?;
d.insert(k, v);
}
}
@ -307,11 +304,10 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
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
let c = match self.peek()? {
None => b' ',
Some(c) if (c as char).is_whitespace() => b' ',
Some(c) => c
};
match c {
b'(' | b')' | b'{' | b'}' | b'[' | b']' | b'<' | b'>' |
@ -351,15 +347,17 @@ 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, S: BinarySource<'de>> Reader<'de> for TextReader<'de, 'src, S>
{
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
fn next_domain<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>> {
self.skip_whitespace();
let c = match self.peek() {
Ok(c) => c,
Err(e) if is_eof_io_error(&e) => return Ok(None),
Err(e) => return Err(e.into()),
let c = match self.peek()? {
None => return Ok(None),
Some(c) => c,
};
Ok(Some(match c {
b'"' => {
@ -372,25 +370,27 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
}
b';' | b'@' => {
if read_annotations {
let mut annotations = self.gather_annotations()?;
let (existing_annotations, v) =
Reader::<N>::demand_next(self, read_annotations)?.pieces();
annotations.extend_from_slice(existing_annotations.slice());
N::wrap(Annotations::new(Some(annotations)), v)
let mut annotations = self.gather_annotations(decode_embedded)?;
let av: N = self.demand_next_domain(read_annotations, decode_embedded)?;
let (existing_annotations, v) = av.pieces();
if let Some(vs) = existing_annotations {
annotations.extend_from_slice(&vs[..]);
}
N::wrap(Some(Box::new(annotations)), v)
} else {
self.skip_annotations()?;
self.demand_next(read_annotations)?
self.demand_next_domain(read_annotations, decode_embedded)?
}
}
b':' => {
return Err(io_syntax_error("Unexpected key/value separator between items"));
return Err(self.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, decode_embedded)?.into_iter())),
b'"' => self.read_literal_binary()?,
b'x' => match self.next_byte()? {
b'"' => N::new(&self.read_hex_binary()?[..]),
@ -399,32 +399,29 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
_ => return Err(io_syntax_error("Invalid #x syntax")),
},
b'[' => self.read_base64_binary()?,
b'!' => {
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))),
b'!' => Value::Embedded(decode_embedded.decode_embedded(self, read_annotations)?).wrap(),
other => return Err(self.syntax_error(&format!("Invalid # syntax: {:?}", other))),
}
}
b'<' => {
self.skip()?;
let vs = self.upto(b'>', read_annotations)?;
let vs = self.upto(b'>', read_annotations, decode_embedded)?;
if vs.is_empty() {
return Err(io_syntax_error("Missing record label"));
return Err(self.syntax_error("Missing record label"));
}
Value::Record(Record(vs)).wrap()
}
b'[' => {
self.skip()?;
N::new(self.upto(b']', read_annotations)?)
N::new(self.upto(b']', read_annotations, decode_embedded)?)
}
b'{' => {
self.skip()?;
self.read_dictionary(read_annotations)?
self.read_dictionary(read_annotations, decode_embedded)?
}
b'>' => return Err(io_syntax_error("Unexpected >")),
b']' => return Err(io_syntax_error("Unexpected ]")),
b'}' => return Err(io_syntax_error("Unexpected }")),
b'>' => return Err(self.syntax_error("Unexpected >")),
b']' => return Err(self.syntax_error("Unexpected ]")),
b'}' => return Err(self.syntax_error("Unexpected }")),
other => {
self.skip()?;
self.read_raw_symbol_or_number(vec![other])?
@ -432,40 +429,23 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
}))
}
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> {
fn open_record(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
if self.peek()? != b'<' { return Err(self.expected::<N>(ExpectedKind::Record(arity))); }
if self.peek()? != Some(b'<') { return Err(Error::Expected(ExpectedKind::Record)); }
self.skip()?;
let mut b = B::Type::default();
Reader::<N>::ensure_more_expected(self, &mut b, &B::Item::RecordLabel)?;
Ok(b)
}
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item> {
self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?;
match self.next_byte()? {
b'#' => match self.next_byte()? {
b'{' => return Ok(B::Item::SetValue),
_ => (),
},
b'[' => return Ok(B::Item::SequenceValue),
_ => (),
}
Reader::<N>::restore(self, &mark)?;
Err(self.expected::<N>(ExpectedKind::SequenceOrSet))
Ok(())
}
fn open_sequence(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
if self.peek()? != b'[' { return Err(self.expected::<N>(ExpectedKind::Sequence)); }
if self.peek()? != Some(b'[') { return Err(Error::Expected(ExpectedKind::Sequence)); }
self.skip()?;
Ok(())
}
fn open_set(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?;
let mark = self.mark()?;
match self.next_byte()? {
b'#' => match self.next_byte()? {
b'{' => return Ok(()),
@ -473,13 +453,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
},
_ => (),
}
Reader::<N>::restore(self, &mark)?;
Err(self.expected::<N>(ExpectedKind::Set))
self.restore(&mark)?;
Err(Error::Expected(ExpectedKind::Set))
}
fn open_dictionary(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
if self.peek()? != b'{' { return Err(self.expected::<N>(ExpectedKind::Dictionary)); }
if self.peek()? != Some(b'{') { return Err(Error::Expected(ExpectedKind::Dictionary)); }
self.skip()?;
Ok(())
}
@ -493,7 +473,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
} => {
self.skip_whitespace();
if self.next_byte()? != b':' {
return Err(syntax_error("Missing expected key/value separator"));
Err(self.syntax_error("Missing expected key/value separator"))?;
}
},
_ => (),
@ -503,14 +483,14 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
fn close_compound(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<bool> {
self.skip_whitespace();
match self.peek()? {
match self.peek_noeof()? {
b'>' | b']' | b'}' => {
self.skip()?;
Ok(true)
}
_ => {
b.shift(Some(i.clone()));
Reader::<N>::boundary(self, b)?;
self.boundary(b)?;
Ok(false)
}
}
@ -518,7 +498,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
fn open_embedded(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?;
let mark = self.mark()?;
match self.next_byte()? {
b'#' => match self.next_byte()? {
b'!' => return Ok(()),
@ -526,8 +506,8 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
},
_ => (),
}
Reader::<N>::restore(self, &mark)?;
Err(self.expected::<N>(ExpectedKind::Embedded))
self.restore(&mark)?;
Err(Error::Expected(ExpectedKind::Embedded))
}
fn close_embedded(&mut self) -> ReaderResult<()> {
@ -544,9 +524,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
self.source.restore(mark)
}
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>> {
fn next_token<D: Domain, Dec: DomainDecode<D>>(
&mut self,
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<D>> {
self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?;
let mark = self.mark()?;
Ok(match self.next_byte()? {
b'<' => Token::Compound(CompoundClass::Record),
b'[' => Token::Compound(CompoundClass::Sequence),
@ -555,25 +539,17 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
b']' => Token::End,
b'}' => Token::End,
b'#' => match self.next_byte()? {
b'!' => {
let v = self.next_iovalue(read_embedded_annotations)?;
Token::Embedded(self.dec.parse_embedded(&v)?)
}
b'!' => Token::Embedded(decode_embedded.decode_embedded(self, read_embedded_annotations)?),
b'{' => Token::Compound(CompoundClass::Set),
_ => {
Reader::<N>::restore(self, &mark)?;
Token::Atom(self.demand_next(false)?)
self.restore(&mark)?;
Token::Atom(self.demand_next_domain(false, decode_embedded)?)
}
},
_ => {
Reader::<N>::restore(self, &mark)?;
Token::Atom(self.demand_next(false)?)
self.restore(&mark)?;
Token::Atom(self.demand_next_domain(false, decode_embedded)?)
}
})
}
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)> {
let annotations = self.gather_annotations()?;
Ok((annotations, self.next_token(true)?))
}
}

View File

@ -4,8 +4,6 @@ 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;
@ -23,7 +21,7 @@ pub enum CommaStyle {
}
pub struct TextWriter<W: io::Write> {
w: Suspendable<W>,
w: W,
pub comma_style: CommaStyle,
pub indentation: usize,
pub escape_spaces: bool,
@ -67,7 +65,7 @@ impl TextWriter<&mut Vec<u8>> {
impl<W: io::Write> TextWriter<W> {
pub fn new(w: W) -> Self {
TextWriter {
w: Suspendable::new(w),
w,
comma_style: CommaStyle::default(),
indentation: 0,
escape_spaces: false,
@ -85,14 +83,6 @@ impl<W: io::Write> TextWriter<W> {
self
}
pub fn suspend(&mut self) -> 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,
@ -148,7 +138,7 @@ impl<W: io::Write> TextWriter<W> {
}
}
impl<W: io::Write> CompoundWriter for TextWriter<W> {
impl<W: io::Write> Writer for TextWriter<W> {
#[inline]
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
match (b.closing.as_ref(), b.opening.as_ref()) {
@ -203,29 +193,12 @@ impl<W: io::Write> CompoundWriter for TextWriter<W> {
Ok(())
}
}
macro_rules! simple_writer_method {
($n:ident, $argty:ty) =>
(fn $n (&mut self, v: $argty) -> io::Result<()> {
write!(self.w, "{}", v)
});
}
impl<W: io::Write> Writer for TextWriter<W> {
type AnnWriter = Self;
type RecWriter = Self;
type SeqWriter = Self;
type SetWriter = Self;
type DictWriter = Self;
type EmbeddedWriter = Self;
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> {
Ok(self.suspend())
fn start_annotations(&mut self) -> io::Result<()> {
Ok(())
}
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> {
self.resume(ann);
fn end_annotations(&mut self) -> io::Result<()> {
Ok(())
}
@ -238,7 +211,7 @@ impl<W: io::Write> Writer for TextWriter<W> {
write!(self.w, "#xf\"{}\"",
HexFormatter::Packed.encode(&u32::to_be_bytes(f32::to_bits(v))))
} else {
dtoa::write(&mut *self.w, v)?;
dtoa::write(&mut self.w, v)?;
write!(self.w, "f")
}
}
@ -248,22 +221,22 @@ impl<W: io::Write> Writer for TextWriter<W> {
write!(self.w, "#xd\"{}\"",
HexFormatter::Packed.encode(&u64::to_be_bytes(f64::to_bits(v))))
} else {
dtoa::write(&mut *self.w, v)?;
dtoa::write(&mut self.w, v)?;
Ok(())
}
}
simple_writer_method!(write_i8, i8);
simple_writer_method!(write_u8, u8);
simple_writer_method!(write_i16, i16);
simple_writer_method!(write_u16, u16);
simple_writer_method!(write_i32, i32);
simple_writer_method!(write_u32, u32);
simple_writer_method!(write_i64, i64);
simple_writer_method!(write_u64, u64);
simple_writer_method!(write_i128, i128);
simple_writer_method!(write_u128, u128);
simple_writer_method!(write_int, &BigInt);
fn write_i128(&mut self, v: i128) -> io::Result<()> {
write!(self.w, "{}", v)
}
fn write_u128(&mut self, v: u128) -> io::Result<()> {
write!(self.w, "{}", v)
}
fn write_int(&mut self, v: &BigInt) -> io::Result<()> {
write!(self.w, "{}", v)
}
fn write_string(&mut self, v: &str) -> io::Result<()> {
write!(self.w, "\"")?;
@ -302,53 +275,43 @@ impl<W: io::Write> Writer for TextWriter<W> {
}
}
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> {
write!(self.w, "<")?;
Ok(self.suspend())
fn start_record(&mut self) -> io::Result<()> {
write!(self.w, "<")
}
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> {
self.resume(rec);
fn end_record(&mut self) -> io::Result<()> {
write!(self.w, ">")
}
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> {
write!(self.w, "[")?;
Ok(self.suspend())
fn start_sequence(&mut self) -> io::Result<()> {
write!(self.w, "[")
}
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> {
self.resume(seq);
fn end_sequence(&mut self) -> io::Result<()> {
write!(self.w, "]")
}
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> {
write!(self.w, "#{{")?;
Ok(self.suspend())
fn start_set(&mut self) -> io::Result<()> {
write!(self.w, "#{{")
}
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> {
self.resume(set);
fn end_set(&mut self) -> io::Result<()> {
write!(self.w, "}}")
}
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> {
write!(self.w, "{{")?;
Ok(self.suspend())
fn start_dictionary(&mut self) -> io::Result<()> {
write!(self.w, "{{")
}
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> {
self.resume(dict);
fn end_dictionary(&mut self) -> io::Result<()> {
write!(self.w, "}}")
}
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> {
write!(self.w, "#!")?;
Ok(self.suspend())
fn start_embedded(&mut self) -> io::Result<()> {
write!(self.w, "#!")
}
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()> {
self.resume(ptr);
fn end_embedded(&mut self) -> io::Result<()> {
Ok(())
}

View File

@ -2,37 +2,19 @@ use num::bigint::BigInt;
use std::io;
use super::DomainEncode;
use super::boundary as B;
use super::signed_integer::SignedInteger;
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<()>;
}
pub trait Writer: Sized {
type AnnWriter: CompoundWriter;
type RecWriter: CompoundWriter;
type SeqWriter: CompoundWriter;
type SetWriter: CompoundWriter;
type DictWriter: CompoundWriter;
type EmbeddedWriter: Writer;
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter>;
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()>;
fn start_annotations(&mut self) -> io::Result<()>;
fn end_annotations(&mut self) -> io::Result<()>;
fn write_bool(&mut self, v: bool) -> io::Result<()>;
fn write_f32(&mut self, v: f32) -> io::Result<()>;
fn write_f64(&mut self, v: f64) -> io::Result<()>;
fn write_i8(&mut self, v: i8) -> io::Result<()>;
fn write_u8(&mut self, v: u8) -> io::Result<()>;
fn write_i16(&mut self, v: i16) -> io::Result<()>;
fn write_u16(&mut self, v: u16) -> io::Result<()>;
fn write_i32(&mut self, v: i32) -> io::Result<()>;
fn write_u32(&mut self, v: u32) -> io::Result<()>;
fn write_i64(&mut self, v: i64) -> io::Result<()>;
fn write_u64(&mut self, v: u64) -> io::Result<()>;
fn write_i128(&mut self, v: i128) -> io::Result<()>;
fn write_u128(&mut self, v: u128) -> io::Result<()>;
fn write_int(&mut self, v: &BigInt) -> io::Result<()>;
@ -41,48 +23,76 @@ pub trait Writer: Sized {
fn write_bytes(&mut self, v: &[u8]) -> io::Result<()>;
fn write_symbol(&mut self, v: &str) -> io::Result<()>;
fn start_record(&mut self, field_count: Option<usize>) -> io::Result<Self::RecWriter>;
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()>;
fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
fn start_sequence(&mut self, item_count: Option<usize>) -> io::Result<Self::SeqWriter>;
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()>;
fn start_record(&mut self) -> io::Result<()>;
fn end_record(&mut self) -> io::Result<()>;
fn start_set(&mut self, item_count: Option<usize>) -> io::Result<Self::SetWriter>;
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()>;
fn start_sequence(&mut self) -> io::Result<()>;
fn end_sequence(&mut self) -> io::Result<()>;
fn start_dictionary(&mut self, entry_count: Option<usize>) -> io::Result<Self::DictWriter>;
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()>;
fn start_set(&mut self) -> io::Result<()>;
fn end_set(&mut self) -> io::Result<()>;
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter>;
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()>;
fn start_dictionary(&mut self) -> io::Result<()>;
fn end_dictionary(&mut self) -> io::Result<()>;
fn start_embedded(&mut self) -> io::Result<()>;
fn end_embedded(&mut self) -> io::Result<()>;
fn flush(&mut self) -> io::Result<()>;
//---------------------------------------------------------------------------
fn write_i8(&mut self, v: i8) -> io::Result<()> { self.write_i128(v as i128) }
fn write_u8(&mut self, v: u8) -> io::Result<()> { self.write_u128(v as u128) }
fn write_i16(&mut self, v: i16) -> io::Result<()> { self.write_i128(v as i128) }
fn write_u16(&mut self, v: u16) -> io::Result<()> { self.write_u128(v as u128) }
fn write_i32(&mut self, v: i32) -> io::Result<()> { self.write_i128(v as i128) }
fn write_u32(&mut self, v: u32) -> io::Result<()> { self.write_u128(v as u128) }
fn write_i64(&mut self, v: i64) -> io::Result<()> { self.write_i128(v as i128) }
fn write_u64(&mut self, v: u64) -> io::Result<()> { self.write_u128(v as u128) }
fn write_signed_integer(&mut self, v: &SignedInteger) -> io::Result<()> {
match v.repr() {
SignedIntegerRepr::I128(i) => self.write_i128(*i),
SignedIntegerRepr::U128(u) => self.write_u128(*u),
SignedIntegerRepr::Big(n) => self.write_int(n),
}
}
#[inline(always)]
fn write<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
&mut self,
enc: &mut Enc,
v: &N,
) -> io::Result<()> {
match v.annotations().maybe_slice() {
self.inner_write(enc, v)
}
fn inner_write<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
&mut self,
enc: &mut Enc,
v: &N,
) -> io::Result<()> {
match v.annotations() {
None => {
self.write_value(enc, v.value())?;
}
Some(anns) => {
let mut a = self.start_annotations()?;
self.start_annotations()?;
let mut b = B::Type::default();
for ann in anns {
for ann in &anns[..] {
b.shift(Some(B::Item::Annotation));
a.boundary(&b)?;
a.write(enc, ann)?;
self.boundary(&b)?;
self.inner_write(enc, ann)?;
}
b.shift(Some(B::Item::AnnotatedValue));
a.boundary(&b)?;
a.write_value(enc, v.value())?;
self.boundary(&b)?;
self.write_value(enc, v.value())?;
b.shift(None);
a.boundary(&b)?;
self.end_annotations(a)?;
self.boundary(&b)?;
self.end_annotations()?;
}
}
Ok(())
@ -97,86 +107,68 @@ pub trait Writer: Sized {
Value::Boolean(b) => self.write_bool(*b),
Value::Float(Float(f)) => self.write_f32(*f),
Value::Double(Double(d)) => self.write_f64(*d),
Value::SignedInteger(n) => match n.repr() {
SignedIntegerRepr::I128(i) => self.write_i128(*i),
SignedIntegerRepr::U128(u) => self.write_u128(*u),
SignedIntegerRepr::Big(n) => self.write_int(n),
}
Value::SignedInteger(n) => self.write_signed_integer(n),
Value::String(s) => self.write_string(s),
Value::ByteString(bs) => self.write_bytes(bs),
Value::Symbol(s) => self.write_symbol(s),
Value::Record(r) => {
let mut c = self.start_record(Some(r.arity()))?;
self.start_record()?;
let mut b = B::start(B::Item::RecordLabel);
c.boundary(&b)?;
c.write(enc, r.label())?;
self.boundary(&b)?;
self.inner_write(enc, r.label())?;
for f in r.fields() {
b.shift(Some(B::Item::RecordField));
c.boundary(&b)?;
c.write(enc, f)?;
self.boundary(&b)?;
self.inner_write(enc, f)?;
}
b.shift(None);
c.boundary(&b)?;
self.end_record(c)
self.boundary(&b)?;
self.end_record()
}
Value::Sequence(vs) => {
let mut c = self.start_sequence(Some(vs.len()))?;
self.start_sequence()?;
let mut b = B::Type::default();
for v in vs {
b.shift(Some(B::Item::SequenceValue));
c.boundary(&b)?;
c.write(enc, v)?;
self.boundary(&b)?;
self.inner_write(enc, v)?;
}
b.shift(None);
c.boundary(&b)?;
self.end_sequence(c)
self.boundary(&b)?;
self.end_sequence()
}
Value::Set(vs) => {
let mut c = self.start_set(Some(vs.len()))?;
self.start_set()?;
let mut b = B::Type::default();
for v in vs {
b.shift(Some(B::Item::SetValue));
c.boundary(&b)?;
c.write(enc, v)?;
self.boundary(&b)?;
self.inner_write(enc, v)?;
}
b.shift(None);
c.boundary(&b)?;
self.end_set(c)
self.boundary(&b)?;
self.end_set()
}
Value::Dictionary(vs) => {
let mut c = self.start_dictionary(Some(vs.len()))?;
self.start_dictionary()?;
let mut b = B::Type::default();
for (k, v) in vs {
b.shift(Some(B::Item::DictionaryKey));
c.boundary(&b)?;
c.write(enc, k)?;
self.boundary(&b)?;
self.inner_write(enc, k)?;
b.shift(Some(B::Item::DictionaryValue));
c.boundary(&b)?;
c.write(enc, v)?;
self.boundary(&b)?;
self.inner_write(enc, v)?;
}
b.shift(None);
c.boundary(&b)?;
self.end_dictionary(c)
self.boundary(&b)?;
self.end_dictionary()
}
Value::Embedded(d) => {
let mut c = self.start_embedded()?;
enc.encode_embedded(&mut c, d)?;
self.end_embedded(c)
self.start_embedded()?;
enc.encode_embedded(self, d)?;
self.end_embedded()
}
}
}
}
pub fn varint<W: io::Write>(w: &mut W, mut v: u64) -> io::Result<usize> {
let mut byte_count = 0;
loop {
byte_count += 1;
if v < 128 {
w.write_all(&[v as u8])?;
return Ok(byte_count);
} else {
w.write_all(&[((v & 0x7f) + 128) as u8])?;
v >>= 7;
}
}
}

View File

@ -1,6 +1,6 @@
use preserves::error::{is_eof_io_error, is_syntax_io_error};
use preserves::symbol::Symbol;
use preserves::value::BinarySource;
use preserves::value::{BinarySource, IOValueDomainCodec};
use preserves::value::BytesBinarySource;
use preserves::value::IOBinarySource;
use preserves::value::IOValue;
@ -14,7 +14,7 @@ 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().configured(true, IOValueDomainCodec).collect()
}
#[test] fn compare_text_with_packed() -> io::Result<()> {
@ -24,13 +24,12 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
let mut contents = String::new();
fh.read_to_string(&mut contents)?;
preserves::value::TextReader::new(
&mut BytesBinarySource::new(contents.as_bytes()),
preserves::value::ViaCodec::new(preserves::value::IOValueDomainCodec))
&mut BytesBinarySource::new(contents.as_bytes()))
.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().next_iovalue(true)?
};
assert_eq!(from_text, from_packed);
Ok(())
@ -105,7 +104,7 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
#[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);
let mut d = src.packed().configured(true, IOValueDomainCodec);
let tests: TestCases = deserialize_from_value(&d.next().unwrap().unwrap()).unwrap();
for (Symbol(ref name), ref case) in tests.tests {
@ -143,14 +142,14 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
}
}
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().next_iovalue(true) {
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().next::<IOValue>(true)?.is_none());
}
}
}

View File

@ -190,7 +190,7 @@ domain-specific rules.
`Embedded` rewriting without the quotation-related complications
of encoding references as, say, `Record`s.
*Examples.* In a Java or Python implementation, an `Embedded` may
*Motivating Examples.* In a Java or Python implementation, an `Embedded` may
denote a reference to a Java or Python object; comparison would be
done via the language's own rules for equivalence and ordering. In a
Unix application, an `Embedded` may denote an open file descriptor or