Change API: as_record() now takes Option<usize>

This commit is contained in:
Tony Garnock-Jones 2020-05-18 16:42:59 +02:00
parent 2a85e53acc
commit 316a772fec
5 changed files with 27 additions and 20 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "preserves"
version = "0.4.0"
version = "0.5.0"
authors = ["Tony Garnock-Jones <tonyg@leastfixedpoint.com>"]
edition = "2018"
description = "Implementation of the Preserves serialization format via serde."

View File

@ -216,7 +216,11 @@ mod value_tests {
#[test] fn record_mut() {
let says = VV::symbol("says").wrap();
let mut r = VV::record(says.clone(), vec![VV::from("Tony").wrap(), VV::from("Hello!").wrap()]);
r.as_record_mut().unwrap().1[0] = VV::from("Alice").wrap();
assert_eq!(r.as_record_mut(Some(0)), None);
assert_eq!(r.as_record_mut(Some(1)), None);
assert!(r.as_record_mut(Some(2)).is_some());
assert_eq!(r.as_record_mut(Some(3)), None);
r.as_record_mut(None).unwrap().1[0] = VV::from("Alice").wrap();
assert_eq!(r, VV::record(says, vec![VV::from("Alice").wrap(), VV::from("Hello!").wrap()]));
}

View File

@ -342,7 +342,7 @@ impl<'a, 'de, N: NestedValue<D>, D: 'de + Domain> EnumAccess<'de> for &'a mut De
fn variant_seed<V>(self, seed: V)
-> Result<(V::Value, Self::Variant), D> where V: DeserializeSeed<'de>
{
let (lp, _) = self.check(|v| v.as_record(), ExpectedKind::Record)?;
let (lp, _) = self.check(|v| v.as_record(None), ExpectedKind::Record(None))?;
let v = self.input;
self.input = N::boxunwrap(lp);
let variant = seed.deserialize(&mut *self)?;
@ -359,18 +359,18 @@ impl<'a, 'de, N: NestedValue<D>, D: 'de + Domain> VariantAccess<'de> for &'a mut
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, D> where T: DeserializeSeed<'de> {
let (_, fs) = self.input.value().as_record().unwrap();
let (_, fs) = self.check(|v| v.as_record(Some(1)), ExpectedKind::Record(Some(1)))?;
self.input = &fs[0];
seed.deserialize(&mut *self)
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, D> where V: Visitor<'de> {
visitor.visit_seq(VecSeq::new(self, &self.input.value().as_record().unwrap().1))
visitor.visit_seq(VecSeq::new(self, &self.input.value().as_record(None).unwrap().1))
}
fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V)
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V)
-> Result<V::Value, D> where V: Visitor<'de>
{
visitor.visit_seq(VecSeq::new(self, &self.input.value().as_record().unwrap().1))
visitor.visit_seq(VecSeq::new(self, &self.input.value().as_record(Some(fields.len())).unwrap().1))
}
}

View File

@ -22,7 +22,7 @@ pub enum ExpectedKind {
ByteString,
Symbol,
Record,
Record(Option<usize>),
SimpleRecord(&'static str, Option<usize>),
Option,
Sequence,

View File

@ -400,20 +400,28 @@ impl<N: NestedValue<D>, D: Domain> Value<N, D> {
}
pub fn is_record(&self) -> bool {
self.as_record().is_some()
self.as_record(None).is_some()
}
pub fn as_record(&self) -> Option<&Record<N, D>> {
pub fn as_record(&self, arity: Option<usize>) -> Option<&Record<N, D>> {
if let Value::Record(ref r) = *self {
Some(r)
match arity {
Some(expected) if r.1.len() == expected => Some(r),
Some(_other) => None,
None => Some(r)
}
} else {
None
}
}
pub fn as_record_mut(&mut self) -> Option<&mut Record<N, D>> {
pub fn as_record_mut(&mut self, arity: Option<usize>) -> Option<&mut Record<N, D>> {
if let Value::Record(ref mut r) = *self {
Some(r)
match arity {
Some(expected) if r.1.len() == expected => Some(r),
Some(_other) => None,
None => Some(r)
}
} else {
None
}
@ -428,14 +436,9 @@ impl<N: NestedValue<D>, D: Domain> Value<N, D> {
}
pub fn as_simple_record(&self, label: &str, arity: Option<usize>) -> Option<&Vec<N>> {
self.as_record().and_then(|(lp,fs)| {
self.as_record(arity).and_then(|(lp,fs)| {
match N::boxunwrap(lp).value() {
Value::Symbol(ref s) if s == label =>
match arity {
Some(expected) if fs.len() == expected => Some(fs),
Some(_other) => None,
None => Some(fs)
}
Value::Symbol(ref s) if s == label => Some(fs),
_ => None
}
})