From f1d403a6a7f0f3254d22b3929b4cbd62687e8991 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Wed, 30 Jun 2021 09:52:16 +0200 Subject: [PATCH] Fallible from_preserves --- implementations/rust/preserves/src/lib.rs | 4 +- .../rust/preserves/src/value/mod.rs | 2 + .../rust/preserves/src/value/packed/mod.rs | 3 +- .../rust/preserves/src/value/packed/reader.rs | 31 ++++++---- .../rust/preserves/src/value/reader.rs | 4 +- .../rust/preserves/src/value/repr.rs | 59 +++++++++++-------- .../rust/preserves/src/value/writer.rs | 20 +++---- 7 files changed, 71 insertions(+), 52 deletions(-) diff --git a/implementations/rust/preserves/src/lib.rs b/implementations/rust/preserves/src/lib.rs index 93dff6b..c92a90a 100644 --- a/implementations/rust/preserves/src/lib.rs +++ b/implementations/rust/preserves/src/lib.rs @@ -11,7 +11,7 @@ pub mod value; #[cfg(test)] mod dom { use super::value::{ - Value, IOValue, NestedValue, PlainValue, Domain, + Value, IOValue, IOResult, NestedValue, PlainValue, Domain, PackedWriter, }; @@ -22,7 +22,7 @@ mod dom { } impl Domain for Dom { - fn from_preserves(v: IOValue) -> Self { + fn from_preserves(v: IOValue) -> IOResult { panic!("Cannot decode IOValue to Dom: {:?}", v); } diff --git a/implementations/rust/preserves/src/value/mod.rs b/implementations/rust/preserves/src/value/mod.rs index b4f074d..1785ca6 100644 --- a/implementations/rust/preserves/src/value/mod.rs +++ b/implementations/rust/preserves/src/value/mod.rs @@ -33,6 +33,8 @@ pub use repr::FALSE; pub use repr::TRUE; pub use repr::EMPTY_SEQ; +pub type IOResult = std::result::Result; + pub fn invert_map(m: &Map) -> Map where A: Clone, B: Clone + Ord { diff --git a/implementations/rust/preserves/src/value/packed/mod.rs b/implementations/rust/preserves/src/value/packed/mod.rs index 71b2b66..952baba 100644 --- a/implementations/rust/preserves/src/value/packed/mod.rs +++ b/implementations/rust/preserves/src/value/packed/mod.rs @@ -5,8 +5,7 @@ pub mod writer; pub use reader::PackedReader; pub use writer::PackedWriter; -use super::{Reader, IOValue}; -use super::reader::IOResult; +use super::{Reader, IOValue, IOResult}; pub fn from_bytes(bs: &[u8]) -> IOResult { PackedReader::decode_bytes(bs).demand_next(false) diff --git a/implementations/rust/preserves/src/value/packed/reader.rs b/implementations/rust/preserves/src/value/packed/reader.rs index 3c811df..d922d3f 100644 --- a/implementations/rust/preserves/src/value/packed/reader.rs +++ b/implementations/rust/preserves/src/value/packed/reader.rs @@ -4,18 +4,29 @@ use std::borrow::Cow; use std::convert::TryFrom; use std::convert::TryInto; use std::marker::PhantomData; -use super::super::signed_integer::SignedInteger; -use super::super::repr::{Value, NestedValue, Domain, IOValue, FALSE, TRUE, Map, Set, Record, Annotations}; use super::constants::Tag; -use super::super::reader::{ - BinarySource, - BytesBinarySource, - ConfiguredReader, - IOBinarySource, +use super::super::{ + FALSE, IOResult, - Reader, - ReaderResult, + IOValue, + Map, + NestedValue, + Record, + Set, + TRUE, + Value, + + reader::{ + BinarySource, + BytesBinarySource, + ConfiguredReader, + IOBinarySource, + Reader, + ReaderResult, + }, + repr::Annotations, + signed_integer::SignedInteger, }; use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_syntax_error}; @@ -264,7 +275,7 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { } Tag::Embedded => { let v = self.demand_next(read_annotations)?; - Value::Domain(IOValue::from_preserves(v)).wrap() + Value::Domain(v).wrap() } Tag::SmallInteger(v) => { // TODO: prebuild these in value.rs diff --git a/implementations/rust/preserves/src/value/reader.rs b/implementations/rust/preserves/src/value/reader.rs index decff35..66ac1fe 100644 --- a/implementations/rust/preserves/src/value/reader.rs +++ b/implementations/rust/preserves/src/value/reader.rs @@ -1,10 +1,10 @@ use std::borrow::Cow; -use std::io::{Read, Error}; +use std::io::Read; use std::marker::PhantomData; use super::repr::{NestedValue, IOValue}; +use super::IOResult; use crate::error::{self, ExpectedKind, Received, io_eof}; -pub type IOResult = std::result::Result; pub type ReaderResult = std::result::Result; pub trait Reader<'de> { diff --git a/implementations/rust/preserves/src/value/repr.rs b/implementations/rust/preserves/src/value/repr.rs index e91b6e3..1cde6fc 100644 --- a/implementations/rust/preserves/src/value/repr.rs +++ b/implementations/rust/preserves/src/value/repr.rs @@ -16,11 +16,12 @@ use std::vec::Vec; pub use std::collections::BTreeSet as Set; pub use std::collections::BTreeMap as Map; +use super::IOResult; use super::signed_integer::SignedInteger; use crate::error::{Error, ExpectedKind, Received}; pub trait Domain: Sized + Debug + Clone + Eq + Hash + Ord { - fn from_preserves(v: IOValue) -> Self; + fn from_preserves(v: IOValue) -> IOResult; fn as_preserves(&self) -> IOValue; } @@ -39,19 +40,19 @@ pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord { self.value().fmt(f) } - fn copy_via, E: Domain, F>(&self, f: &F) -> M + fn copy_via, E: Domain, F>(&self, f: &F) -> IOResult where - F: Fn(&D) -> Value + F: Fn(&D) -> IOResult> { - M::wrap(self.annotations().copy_via(f), self.value().copy_via(f)) + Ok(M::wrap(self.annotations().copy_via(f)?, self.value().copy_via(f)?)) } fn to_io_value(&self) -> IOValue { - self.copy_via(&|d| d.as_preserves().value().clone()) + self.copy_via(&|d| Ok(d.as_preserves().value().clone())).unwrap() } - fn from_io_value(v: &IOValue) -> Self { - v.copy_via(&|d| Value::Domain(D::from_preserves(d.clone()))) + fn from_io_value(v: &IOValue) -> IOResult { + v.copy_via(&|d| Ok(Value::Domain(D::from_preserves(d.clone())?))) } } @@ -739,11 +740,11 @@ impl, D: Domain> Value { self.as_embedded().ok_or_else(|| self.expected(ExpectedKind::Embedded)) } - pub fn copy_via, E: Domain, F>(&self, f: &F) -> Value + pub fn copy_via, E: Domain, F>(&self, f: &F) -> IOResult> where - F: Fn(&D) -> Value + F: Fn(&D) -> IOResult> { - match self { + Ok(match self { Value::Boolean(b) => Value::Boolean(*b), Value::Float(f) => Value::Float(f.clone()), Value::Double(d) => Value::Double(d.clone()), @@ -752,13 +753,17 @@ impl, D: Domain> Value { Value::ByteString(ref v) => Value::ByteString(v.clone()), Value::Symbol(ref v) => Value::Symbol(v.clone()), Value::Record(ref r) => - Value::Record(Record(r.fields_vec().iter().map(|a| a.copy_via(f)).collect())), - Value::Sequence(ref v) => Value::Sequence(v.iter().map(|a| a.copy_via(f)).collect()), - Value::Set(ref v) => Value::Set(v.iter().map(|a| a.copy_via(f)).collect()), + Value::Record(Record(r.fields_vec().iter().map(|a| a.copy_via(f)) + .collect::, _>>()?)), + Value::Sequence(ref v) => Value::Sequence(v.iter().map(|a| a.copy_via(f)) + .collect::>>()?), + Value::Set(ref v) => Value::Set(v.iter().map(|a| a.copy_via(f)) + .collect::>>()?), Value::Dictionary(ref v) => - Value::Dictionary(v.iter().map(|(a,b)| (a.copy_via(f), b.copy_via(f))).collect()), - Value::Domain(d) => f(d), - } + Value::Dictionary(v.iter().map(|(a,b)| Ok((a.copy_via(f)?, b.copy_via(f)?))) + .collect::>>()?), + Value::Domain(d) => f(d)?, + }) } } @@ -808,7 +813,8 @@ pub fn serialize_nested_value(v: &N, serializer: S) -> pub fn deserialize_nested_value<'de, D, N, Dom: Domain>(deserializer: D) -> Result where D: serde::Deserializer<'de>, N: NestedValue + serde::Deserialize<'de> { - Ok(N::from_io_value(&super::magic::input_value(deserializer)?)) + N::from_io_value(&super::magic::input_value(deserializer)?) + .map_err(|e| serde::de::Error::custom(format!("{:?}", e))) } //--------------------------------------------------------------------------- @@ -847,16 +853,17 @@ impl, D: Domain> Annotations { self } - pub fn copy_via, E: Domain, F>(&self, f: &F) -> Annotations + pub fn copy_via, E: Domain, F>(&self, f: &F) -> IOResult> where - F: Fn(&D) -> Value + F: Fn(&D) -> IOResult> { - match self.0 { + Ok(match self.0 { None => Annotations(None, PhantomData), Some(ref b) => - Annotations(Some(b.iter().map(|a| a.copy_via(f)).collect()), PhantomData), - } + Annotations(Some(b.iter().map(|a| a.copy_via(f)).collect::, _>>()?), + PhantomData), + }) } } @@ -1060,8 +1067,8 @@ pub struct IOValue(Arc>); pub type UnwrappedIOValue = Value; impl Domain for IOValue { - fn from_preserves(v: IOValue) -> Self { - v + fn from_preserves(v: IOValue) -> IOResult { + Ok(v) } fn as_preserves(&self) -> IOValue { @@ -1106,8 +1113,8 @@ impl NestedValue for IOValue { self.clone() } - fn from_io_value(v: &IOValue) -> Self { - v.clone() + fn from_io_value(v: &IOValue) -> IOResult { + Ok(v.clone()) } } diff --git a/implementations/rust/preserves/src/value/writer.rs b/implementations/rust/preserves/src/value/writer.rs index fdce3dc..b6272a8 100644 --- a/implementations/rust/preserves/src/value/writer.rs +++ b/implementations/rust/preserves/src/value/writer.rs @@ -1,7 +1,7 @@ use num::bigint::BigInt; use std::io::Error; use super::signed_integer::SignedIntegerRepr; -use super::repr::{Domain, Value, NestedValue, IOValue, UnwrappedIOValue, Float, Double}; +use super::repr::{Value, NestedValue, IOValue, UnwrappedIOValue, Float, Double}; pub type Result = std::result::Result; @@ -87,11 +87,11 @@ pub trait Writer: Sized { Value::SignedInteger(n) => match n.repr() { SignedIntegerRepr::I128(i) => self.write_i128(*i), SignedIntegerRepr::U128(u) => self.write_u128(*u), - SignedIntegerRepr::Big(ref n) => self.write_int(n), + SignedIntegerRepr::Big(n) => self.write_int(n), } - Value::String(ref s) => self.write_string(s), - Value::ByteString(ref bs) => self.write_bytes(bs), - Value::Symbol(ref s) => self.write_symbol(s), + 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()))?; c.extend()?; @@ -104,7 +104,7 @@ pub trait Writer: Sized { } self.end_seq(c) } - Value::Sequence(ref vs) => { + Value::Sequence(vs) => { let mut c = self.start_sequence(Some(vs.len()))?; for v in vs { c.extend()?; @@ -113,7 +113,7 @@ pub trait Writer: Sized { } self.end_seq(c) } - Value::Set(ref vs) => { + Value::Set(vs) => { let mut c = self.start_set(Some(vs.len()))?; for v in vs { c.extend()?; @@ -122,7 +122,7 @@ pub trait Writer: Sized { } self.end_set(c) } - Value::Dictionary(ref vs) => { + Value::Dictionary(vs) => { let mut c = self.start_dictionary(Some(vs.len()))?; for (k, v) in vs { c.extend()?; @@ -132,9 +132,9 @@ pub trait Writer: Sized { } self.end_set(c) } - Value::Domain(ref d) => { + Value::Domain(d) => { let mut c = self.start_embedded()?; - c.write(&d.as_preserves())?; + c.write(&d)?; self.end_embedded(c) } }