More
This commit is contained in:
parent
71a45d7808
commit
c93fea0545
|
@ -58,29 +58,29 @@ pub trait Value<D: Domain>: Debug {
|
||||||
fn as_double(&self) -> Option<f64> { None }
|
fn as_double(&self) -> Option<f64> { None }
|
||||||
|
|
||||||
fn is_signed_integer(&self) -> bool { false }
|
fn is_signed_integer(&self) -> bool { false }
|
||||||
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> { None }
|
fn as_signed_integer(&self) -> Option<SignedInteger> { None }
|
||||||
|
|
||||||
fn as_string(&self) -> Option<Cow<'_, str>> { None }
|
fn as_string(&self) -> Option<Cow<'_, str>> { None }
|
||||||
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { None }
|
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { None }
|
||||||
fn as_symbol(&self) -> Option<Cow<'_, str>> { None }
|
fn as_symbol(&self) -> Option<Cow<'_, str>> { None }
|
||||||
|
|
||||||
fn is_record(&self) -> bool { false }
|
fn is_record(&self) -> bool { false }
|
||||||
fn label(&self) -> Option<&dyn Value<D>> { None }
|
fn label(&self) -> &dyn Value<D> { panic!("Not a record") }
|
||||||
|
|
||||||
fn is_sequence(&self) -> bool { false }
|
fn is_sequence(&self) -> bool { false }
|
||||||
fn len(&self) -> Option<usize> { None }
|
fn len(&self) -> usize { panic!("Has no length") }
|
||||||
fn index(&self, _i: usize) -> &dyn Value<D> { panic!("Not a sequence") }
|
fn index(&self, _i: usize) -> &dyn Value<D> { panic!("Not indexable") }
|
||||||
fn iter(&self) -> Option<Box<dyn Iterator<Item = &dyn Value<D>> + '_>> { None }
|
fn iter(&self) -> Box<dyn Iterator<Item = &dyn Value<D>> + '_> { panic!("Not iterable") }
|
||||||
|
|
||||||
fn is_set(&self) -> bool { false }
|
fn is_set(&self) -> bool { false }
|
||||||
fn has(&self, _v: &dyn Value<D>) -> bool { false }
|
fn has(&self, _v: &dyn Value<D>) -> bool { false }
|
||||||
|
|
||||||
fn is_dictionary(&self) -> bool { false }
|
fn is_dictionary(&self) -> bool { false }
|
||||||
fn get(&self, _k: &dyn Value<D>) -> Option<&dyn Value<D>> { None }
|
fn get(&self, _k: &dyn Value<D>) -> Option<&dyn Value<D>> { None }
|
||||||
fn entries(&self) -> Option<Box<dyn Iterator<Item = (&dyn Value<D>, &dyn Value<D>)> + '_>> { None }
|
fn entries(&self) -> Box<dyn Iterator<Item = (&dyn Value<D>, &dyn Value<D>)> + '_> { panic!("Not a dictionary") }
|
||||||
|
|
||||||
fn is_embedded(&self) -> bool { false }
|
fn is_embedded(&self) -> bool { false }
|
||||||
fn embedded(&self) -> Option<Cow<'_, D>> { None }
|
fn embedded(&self) -> Cow<'_, D> { panic!("Not an embedded value") }
|
||||||
|
|
||||||
fn annotations(&self) -> Option<&[Box<dyn Value<D>>]> { None }
|
fn annotations(&self) -> Option<&[Box<dyn Value<D>>]> { None }
|
||||||
}
|
}
|
||||||
|
@ -89,28 +89,33 @@ pub fn value<D: Domain, V: Value<D>>(v: &V) -> &dyn Value<D> {
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn owned<D: Domain, V: Value<D> + 'static>(v: V) -> Box<dyn Value<D>> {
|
||||||
|
Box::new(v)
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, D: Domain, V: Value<D> + ?Sized> Value<D> for &'a V {
|
impl<'a, D: Domain, V: Value<D> + ?Sized> Value<D> for &'a V {
|
||||||
fn value_class(&self) -> ValueClass { (*self).value_class() }
|
fn value_class(&self) -> ValueClass { (*self).value_class() }
|
||||||
fn as_boolean(&self) -> Option<bool> { (*self).as_boolean() }
|
fn as_boolean(&self) -> Option<bool> { (*self).as_boolean() }
|
||||||
fn as_float(&self) -> Option<f32> { (*self).as_float() }
|
fn as_float(&self) -> Option<f32> { (*self).as_float() }
|
||||||
fn as_double(&self) -> Option<f64> { (*self).as_double() }
|
fn as_double(&self) -> Option<f64> { (*self).as_double() }
|
||||||
fn is_signed_integer(&self) -> bool { (*self).is_signed_integer() }
|
fn is_signed_integer(&self) -> bool { (*self).is_signed_integer() }
|
||||||
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> { (*self).as_signed_integer() }
|
fn as_signed_integer(&self) -> Option<SignedInteger> { (*self).as_signed_integer() }
|
||||||
fn as_string(&self) -> Option<Cow<'_, str>> { (*self).as_string() }
|
fn as_string(&self) -> Option<Cow<'_, str>> { (*self).as_string() }
|
||||||
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { (*self).as_bytestring() }
|
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { (*self).as_bytestring() }
|
||||||
fn as_symbol(&self) -> Option<Cow<'_, str>> { (*self).as_symbol() }
|
fn as_symbol(&self) -> Option<Cow<'_, str>> { (*self).as_symbol() }
|
||||||
fn is_record(&self) -> bool { (*self).is_record() }
|
fn is_record(&self) -> bool { (*self).is_record() }
|
||||||
fn label(&self) -> Option<&dyn Value<D>> { (*self).label() }
|
fn label(&self) -> &dyn Value<D> { (*self).label() }
|
||||||
fn is_sequence(&self) -> bool { (*self).is_sequence() }
|
fn is_sequence(&self) -> bool { (*self).is_sequence() }
|
||||||
fn len(&self) -> Option<usize> { (*self).len() }
|
fn len(&self) -> usize { (*self).len() }
|
||||||
fn index(&self, i: usize) -> &dyn Value<D> { (*self).index(i) }
|
fn index(&self, i: usize) -> &dyn Value<D> { (*self).index(i) }
|
||||||
|
fn iter(&self) -> Box<dyn Iterator<Item = &dyn Value<D>> + '_> { (*self).iter() }
|
||||||
fn is_set(&self) -> bool { (*self).is_set() }
|
fn is_set(&self) -> bool { (*self).is_set() }
|
||||||
fn has(&self, v: &dyn Value<D>) -> bool { (*self).has(v) }
|
fn has(&self, v: &dyn Value<D>) -> bool { (*self).has(v) }
|
||||||
fn is_dictionary(&self) -> bool { (*self).is_dictionary() }
|
fn is_dictionary(&self) -> bool { (*self).is_dictionary() }
|
||||||
fn get(&self, k: &dyn Value<D>) -> Option<&dyn Value<D>> { (*self).get(k) }
|
fn get(&self, k: &dyn Value<D>) -> Option<&dyn Value<D>> { (*self).get(k) }
|
||||||
fn entries(&self) -> Option<Box<dyn Iterator<Item = (&dyn Value<D>, &dyn Value<D>)> + '_>> { (*self).entries() }
|
fn entries(&self) -> Box<dyn Iterator<Item = (&dyn Value<D>, &dyn Value<D>)> + '_> { (*self).entries() }
|
||||||
fn is_embedded(&self) -> bool { (*self).is_embedded() }
|
fn is_embedded(&self) -> bool { (*self).is_embedded() }
|
||||||
fn embedded(&self) -> Option<Cow<'_, D>> { (*self).embedded() }
|
fn embedded(&self) -> Cow<'_, D> { (*self).embedded() }
|
||||||
fn annotations(&self) -> Option<&[Box<dyn Value<D>>]> { (*self).annotations() }
|
fn annotations(&self) -> Option<&[Box<dyn Value<D>>]> { (*self).annotations() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,22 +125,23 @@ impl<D: Domain> Value<D> for Box<dyn Value<D>> {
|
||||||
fn as_float(&self) -> Option<f32> { self.as_ref().as_float() }
|
fn as_float(&self) -> Option<f32> { self.as_ref().as_float() }
|
||||||
fn as_double(&self) -> Option<f64> { self.as_ref().as_double() }
|
fn as_double(&self) -> Option<f64> { self.as_ref().as_double() }
|
||||||
fn is_signed_integer(&self) -> bool { self.as_ref().is_signed_integer() }
|
fn is_signed_integer(&self) -> bool { self.as_ref().is_signed_integer() }
|
||||||
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> { self.as_ref().as_signed_integer() }
|
fn as_signed_integer(&self) -> Option<SignedInteger> { self.as_ref().as_signed_integer() }
|
||||||
fn as_string(&self) -> Option<Cow<'_, str>> { self.as_ref().as_string() }
|
fn as_string(&self) -> Option<Cow<'_, str>> { self.as_ref().as_string() }
|
||||||
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { self.as_ref().as_bytestring() }
|
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { self.as_ref().as_bytestring() }
|
||||||
fn as_symbol(&self) -> Option<Cow<'_, str>> { self.as_ref().as_symbol() }
|
fn as_symbol(&self) -> Option<Cow<'_, str>> { self.as_ref().as_symbol() }
|
||||||
fn is_record(&self) -> bool { self.as_ref().is_record() }
|
fn is_record(&self) -> bool { self.as_ref().is_record() }
|
||||||
fn label(&self) -> Option<&dyn Value<D>> { self.as_ref().label() }
|
fn label(&self) -> &dyn Value<D> { self.as_ref().label() }
|
||||||
fn is_sequence(&self) -> bool { self.as_ref().is_sequence() }
|
fn is_sequence(&self) -> bool { self.as_ref().is_sequence() }
|
||||||
fn len(&self) -> Option<usize> { self.as_ref().len() }
|
fn len(&self) -> usize { self.as_ref().len() }
|
||||||
fn index(&self, i: usize) -> &dyn Value<D> { self.as_ref().index(i) }
|
fn index(&self, i: usize) -> &dyn Value<D> { self.as_ref().index(i) }
|
||||||
|
fn iter(&self) -> Box<dyn Iterator<Item = &dyn Value<D>> + '_> { self.as_ref().iter() }
|
||||||
fn is_set(&self) -> bool { self.as_ref().is_set() }
|
fn is_set(&self) -> bool { self.as_ref().is_set() }
|
||||||
fn has(&self, v: &dyn Value<D>) -> bool { self.as_ref().has(v) }
|
fn has(&self, v: &dyn Value<D>) -> bool { self.as_ref().has(v) }
|
||||||
fn is_dictionary(&self) -> bool { self.as_ref().is_dictionary() }
|
fn is_dictionary(&self) -> bool { self.as_ref().is_dictionary() }
|
||||||
fn get(&self, k: &dyn Value<D>) -> Option<&dyn Value<D>> { self.as_ref().get(k) }
|
fn get(&self, k: &dyn Value<D>) -> Option<&dyn Value<D>> { self.as_ref().get(k) }
|
||||||
fn entries(&self) -> Option<Box<dyn Iterator<Item = (&dyn Value<D>, &dyn Value<D>)> + '_>> { self.as_ref().entries() }
|
fn entries(&self) -> Box<dyn Iterator<Item = (&dyn Value<D>, &dyn Value<D>)> + '_> { self.as_ref().entries() }
|
||||||
fn is_embedded(&self) -> bool { self.as_ref().is_embedded() }
|
fn is_embedded(&self) -> bool { self.as_ref().is_embedded() }
|
||||||
fn embedded(&self) -> Option<Cow<'_, D>> { self.as_ref().embedded() }
|
fn embedded(&self) -> Cow<'_, D> { self.as_ref().embedded() }
|
||||||
fn annotations(&self) -> Option<&[Box<dyn Value<D>>]> { self.as_ref().annotations() }
|
fn annotations(&self) -> Option<&[Box<dyn Value<D>>]> { self.as_ref().annotations() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,23 +160,23 @@ impl<'a, D: Domain> Hash for dyn Value<D> + 'a {
|
||||||
ValueClass::Compound(c) => match c {
|
ValueClass::Compound(c) => match c {
|
||||||
CompoundClass::Sequence |
|
CompoundClass::Sequence |
|
||||||
CompoundClass::Set => {
|
CompoundClass::Set => {
|
||||||
state.write_usize(self.len().unwrap());
|
state.write_usize(self.len());
|
||||||
for v in self.iter().unwrap() { v.hash(state) }
|
for v in self.iter() { v.hash(state) }
|
||||||
}
|
}
|
||||||
CompoundClass::Record => {
|
CompoundClass::Record => {
|
||||||
self.label().unwrap().hash(state);
|
self.label().hash(state);
|
||||||
state.write_usize(self.len().unwrap());
|
state.write_usize(self.len());
|
||||||
for v in self.iter().unwrap() { v.hash(state) }
|
for v in self.iter() { v.hash(state) }
|
||||||
}
|
}
|
||||||
CompoundClass::Dictionary => {
|
CompoundClass::Dictionary => {
|
||||||
state.write_usize(self.len().unwrap());
|
state.write_usize(self.len());
|
||||||
for (k, v) in self.entries().unwrap() {
|
for (k, v) in self.entries() {
|
||||||
k.hash(state);
|
k.hash(state);
|
||||||
v.hash(state);
|
v.hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ValueClass::Embedded => self.embedded().unwrap().hash(state),
|
ValueClass::Embedded => self.embedded().hash(state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,24 +219,45 @@ impl<'a, D: Domain> PartialEq for dyn Value<D> + 'a {
|
||||||
}
|
}
|
||||||
ValueClass::Compound(c) => match c {
|
ValueClass::Compound(c) => match c {
|
||||||
CompoundClass::Record => {
|
CompoundClass::Record => {
|
||||||
if self.label().unwrap() != other.label().unwrap() { return false; }
|
if self.label() != other.label() { return false; }
|
||||||
iters_eq(self.iter().unwrap(), other.iter().unwrap())
|
iters_eq(self.iter(), other.iter())
|
||||||
}
|
}
|
||||||
CompoundClass::Sequence => {
|
CompoundClass::Sequence => {
|
||||||
iters_eq(self.iter().unwrap(), other.iter().unwrap())
|
iters_eq(self.iter(), other.iter())
|
||||||
}
|
}
|
||||||
CompoundClass::Set => {
|
CompoundClass::Set => {
|
||||||
let s1 = self.iter().unwrap().collect::<Set<_>>();
|
let s1 = self.iter().collect::<Set<_>>();
|
||||||
let s2 = other.iter().unwrap().collect::<Set<_>>();
|
let s2 = other.iter().collect::<Set<_>>();
|
||||||
s1 == s2
|
s1 == s2
|
||||||
}
|
}
|
||||||
CompoundClass::Dictionary => {
|
CompoundClass::Dictionary => {
|
||||||
let d1 = self.entries().unwrap().collect::<Map<_, _>>();
|
let d1 = self.entries().collect::<Map<_, _>>();
|
||||||
let d2 = other.entries().unwrap().collect::<Map<_, _>>();
|
let d2 = other.entries().collect::<Map<_, _>>();
|
||||||
d1 == d2
|
d1 == d2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ValueClass::Embedded => self.embedded().unwrap() == other.embedded().unwrap(),
|
ValueClass::Embedded => self.embedded() == other.embedded(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iters_cmp<'a, D: Domain>(
|
||||||
|
mut i1: Box<dyn Iterator<Item = &dyn Value<D>> + 'a>,
|
||||||
|
mut i2: Box<dyn Iterator<Item = &dyn Value<D>> + 'a>,
|
||||||
|
) -> Ordering {
|
||||||
|
loop {
|
||||||
|
match i1.next() {
|
||||||
|
None => match i2.next() {
|
||||||
|
None => return Ordering::Equal,
|
||||||
|
Some(_) => return Ordering::Less,
|
||||||
|
}
|
||||||
|
Some(v1) => match i2.next() {
|
||||||
|
None => return Ordering::Greater,
|
||||||
|
Some(v2) => match v1.cmp(v2) {
|
||||||
|
Ordering::Equal => (),
|
||||||
|
other => return other,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,33 +265,41 @@ impl<'a, D: Domain> PartialEq for dyn Value<D> + 'a {
|
||||||
impl<'a, D: Domain> Ord for dyn Value<D> + 'a {
|
impl<'a, D: Domain> Ord for dyn Value<D> + 'a {
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
let cls = self.value_class();
|
let cls = self.value_class();
|
||||||
match cls.cmp(&other.value_class()) {
|
cls.cmp(&other.value_class()).then_with(|| match cls {
|
||||||
Ordering::Less => Ordering::Less,
|
ValueClass::Atomic(a) => match a {
|
||||||
Ordering::Greater => Ordering::Greater,
|
AtomClass::Boolean =>
|
||||||
Ordering::Equal => match cls {
|
self.as_boolean().cmp(&other.as_boolean()),
|
||||||
ValueClass::Atomic(a) => match a {
|
AtomClass::Float =>
|
||||||
AtomClass::Boolean =>
|
Float(self.as_float().unwrap()).cmp(&Float(other.as_float().unwrap())),
|
||||||
self.as_boolean().cmp(&other.as_boolean()),
|
AtomClass::Double =>
|
||||||
AtomClass::Float =>
|
Double(self.as_double().unwrap()).cmp(&Double(other.as_double().unwrap())),
|
||||||
Float(self.as_float().unwrap()).cmp(&Float(other.as_float().unwrap())),
|
AtomClass::SignedInteger =>
|
||||||
AtomClass::Double =>
|
self.as_signed_integer().cmp(&other.as_signed_integer()),
|
||||||
Double(self.as_double().unwrap()).cmp(&Double(other.as_double().unwrap())),
|
AtomClass::String =>
|
||||||
AtomClass::SignedInteger =>
|
self.as_string().cmp(&other.as_string()),
|
||||||
self.as_signed_integer().cmp(&other.as_signed_integer()),
|
AtomClass::ByteString =>
|
||||||
AtomClass::String =>
|
self.as_bytestring().cmp(&other.as_bytestring()),
|
||||||
self.as_string().cmp(&other.as_string()),
|
AtomClass::Symbol =>
|
||||||
AtomClass::ByteString =>
|
self.as_symbol().cmp(&other.as_symbol()),
|
||||||
self.as_bytestring().cmp(&other.as_bytestring()),
|
},
|
||||||
AtomClass::Symbol =>
|
ValueClass::Compound(c) => match c {
|
||||||
self.as_symbol().cmp(&other.as_symbol()),
|
CompoundClass::Record =>
|
||||||
},
|
self.label().cmp(other.label()).then_with(
|
||||||
ValueClass::Compound(c) => match c {
|
|| iters_cmp(self.iter(), other.iter())),
|
||||||
_ => todo!(),
|
CompoundClass::Sequence => iters_cmp(self.iter(), other.iter()),
|
||||||
},
|
CompoundClass::Set => {
|
||||||
ValueClass::Embedded =>
|
let s1 = self.iter().collect::<Set<_>>();
|
||||||
self.embedded().cmp(&other.embedded()),
|
let s2 = other.iter().collect::<Set<_>>();
|
||||||
}
|
s1.cmp(&s2)
|
||||||
}
|
}
|
||||||
|
CompoundClass::Dictionary => {
|
||||||
|
let d1 = self.entries().collect::<Map<_, _>>();
|
||||||
|
let d2 = other.entries().collect::<Map<_, _>>();
|
||||||
|
d1.cmp(&d2)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ValueClass::Embedded => self.embedded().cmp(&other.embedded()),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,8 +327,8 @@ impl<D: Domain> Value<D> for bool {
|
||||||
|
|
||||||
impl<D: Domain> Value<D> for u64 {
|
impl<D: Domain> Value<D> for u64 {
|
||||||
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::SignedInteger) }
|
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::SignedInteger) }
|
||||||
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> {
|
fn as_signed_integer(&self) -> Option<SignedInteger> {
|
||||||
Some(Cow::Owned((*self).into()))
|
Some((*self).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,30 +351,30 @@ impl<D: Domain> Value<D> for String {
|
||||||
impl<D: Domain, V: Value<D>> Value<D> for Vec<V> {
|
impl<D: Domain, V: Value<D>> Value<D> for Vec<V> {
|
||||||
fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Sequence) }
|
fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Sequence) }
|
||||||
fn is_sequence(&self) -> bool { true }
|
fn is_sequence(&self) -> bool { true }
|
||||||
fn len(&self) -> Option<usize> { Some(self.len()) }
|
fn len(&self) -> usize { self.len() }
|
||||||
fn index(&self, i: usize) -> &dyn Value<D> { &self[i] }
|
fn index(&self, i: usize) -> &dyn Value<D> { &self[i] }
|
||||||
fn iter(&self) -> Option<Box<dyn Iterator<Item = &dyn Value<D>> + '_>> {
|
fn iter(&self) -> Box<dyn Iterator<Item = &dyn Value<D>> + '_> {
|
||||||
Some(Box::new(self[..].iter().map(value)))
|
Box::new(self[..].iter().map(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Domain, V: Value<D>> Value<D> for [V] {
|
impl<D: Domain, V: Value<D>> Value<D> for [V] {
|
||||||
fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Sequence) }
|
fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Sequence) }
|
||||||
fn is_sequence(&self) -> bool { true }
|
fn is_sequence(&self) -> bool { true }
|
||||||
fn len(&self) -> Option<usize> { Some(self.len()) }
|
fn len(&self) -> usize { self.len() }
|
||||||
fn index(&self, i: usize) -> &dyn Value<D> { &self[i] }
|
fn index(&self, i: usize) -> &dyn Value<D> { &self[i] }
|
||||||
fn iter(&self) -> Option<Box<dyn Iterator<Item = &dyn Value<D>> + '_>> {
|
fn iter(&self) -> Box<dyn Iterator<Item = &dyn Value<D>> + '_> {
|
||||||
Some(Box::new(self[..].iter().map(value)))
|
Box::new(self[..].iter().map(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Domain> Value<D> for Set<Box<dyn Value<D>>> {
|
impl<D: Domain> Value<D> for Set<Box<dyn Value<D>>> {
|
||||||
fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Set) }
|
fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Set) }
|
||||||
fn is_set(&self) -> bool { true }
|
fn is_set(&self) -> bool { true }
|
||||||
fn len(&self) -> Option<usize> { Some(self.len()) }
|
fn len(&self) -> usize { self.len() }
|
||||||
fn has(&self, v: &dyn Value<D>) -> bool { self.contains(v) }
|
fn has(&self, v: &dyn Value<D>) -> bool { self.contains(v) }
|
||||||
fn iter(&self) -> Option<Box<dyn Iterator<Item = &dyn Value<D>> + '_>> {
|
fn iter(&self) -> Box<dyn Iterator<Item = &dyn Value<D>> + '_> {
|
||||||
Some(Box::new(self.iter().map(value)))
|
Box::new(self.iter().map(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +396,7 @@ impl<'a, 'b: 'a, D: Domain> Borrow<Key<'a, D>> for Box<dyn Value<D> + 'b> {
|
||||||
impl<D: Domain, V: Value<D>> Value<D> for Map<Box<dyn Value<D>>, V> {
|
impl<D: Domain, V: Value<D>> Value<D> for Map<Box<dyn Value<D>>, V> {
|
||||||
fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Dictionary) }
|
fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Dictionary) }
|
||||||
fn is_dictionary(&self) -> bool { true }
|
fn is_dictionary(&self) -> bool { true }
|
||||||
fn len(&self) -> Option<usize> { Some(self.len()) }
|
fn len(&self) -> usize { self.len() }
|
||||||
fn has(&self, v: &dyn Value<D>) -> bool { self.contains_key(v) }
|
fn has(&self, v: &dyn Value<D>) -> bool { self.contains_key(v) }
|
||||||
fn get(&self, k: &dyn Value<D>) -> Option<&dyn Value<D>> {
|
fn get(&self, k: &dyn Value<D>) -> Option<&dyn Value<D>> {
|
||||||
match Map::get(self, Key::wrap_ref(&k)) {
|
match Map::get(self, Key::wrap_ref(&k)) {
|
||||||
|
@ -369,20 +404,38 @@ impl<D: Domain, V: Value<D>> Value<D> for Map<Box<dyn Value<D>>, V> {
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn entries(&self) -> Option<Box<dyn Iterator<Item = (&dyn Value<D>, &dyn Value<D>)> + '_>> {
|
fn entries(&self) -> Box<dyn Iterator<Item = (&dyn Value<D>, &dyn Value<D>)> + '_> {
|
||||||
Some(Box::new(self.iter().map(|(k,v)| (value(k), value(v)))))
|
Box::new(self.iter().map(|(k,v)| (value(k), value(v))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub struct Record<V>(Vec<V> /* at least one element, for the label */);
|
pub struct Record<V>(Vec<V> /* at least one element, for the label */);
|
||||||
|
|
||||||
|
impl<V> Record<V> {
|
||||||
|
pub fn new(label: V, mut fields: Vec<V>) -> Self {
|
||||||
|
fields.insert(0, label);
|
||||||
|
Record(fields)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<D: Domain, V: Value<D>> Value<D> for Record<V> {
|
impl<D: Domain, V: Value<D>> Value<D> for Record<V> {
|
||||||
fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Record) }
|
fn value_class(&self) -> ValueClass { ValueClass::Compound(CompoundClass::Record) }
|
||||||
fn is_record(&self) -> bool { true }
|
fn is_record(&self) -> bool { true }
|
||||||
fn label(&self) -> Option<&dyn Value<D>> { Some(&self.0[0]) }
|
fn label(&self) -> &dyn Value<D> { &self.0[0] }
|
||||||
fn len(&self) -> Option<usize> { Some(self.0.len() - 1) }
|
fn len(&self) -> usize { self.0.len() - 1 }
|
||||||
fn index(&self, i: usize) -> &dyn Value<D> { &self.0[i + 1] }
|
fn index(&self, i: usize) -> &dyn Value<D> { &self.0[i + 1] }
|
||||||
|
fn iter(&self) -> Box<dyn Iterator<Item = &dyn Value<D>> + '_> {
|
||||||
|
Box::new(self.0[1..].iter().map(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
|
pub struct Symbol<T: AsRef<str> + Debug>(T);
|
||||||
|
|
||||||
|
impl<T: AsRef<str> + Debug, D: Domain> Value<D> for Symbol<T> {
|
||||||
|
fn value_class(&self) -> ValueClass { ValueClass::Atomic(AtomClass::Symbol) }
|
||||||
|
fn as_symbol(&self) -> Option<Cow<'_, str>> { Some(Cow::Borrowed(self.0.as_ref())) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -400,22 +453,23 @@ impl<D: Domain, V: Value<D>> Value<D> for Annotations<D, V> {
|
||||||
fn as_float(&self) -> Option<f32> { self.value().as_float() }
|
fn as_float(&self) -> Option<f32> { self.value().as_float() }
|
||||||
fn as_double(&self) -> Option<f64> { self.value().as_double() }
|
fn as_double(&self) -> Option<f64> { self.value().as_double() }
|
||||||
fn is_signed_integer(&self) -> bool { self.value().is_signed_integer() }
|
fn is_signed_integer(&self) -> bool { self.value().is_signed_integer() }
|
||||||
fn as_signed_integer(&self) -> Option<Cow<'_, SignedInteger>> { self.value().as_signed_integer() }
|
fn as_signed_integer(&self) -> Option<SignedInteger> { self.value().as_signed_integer() }
|
||||||
fn as_string(&self) -> Option<Cow<'_, str>> { self.value().as_string() }
|
fn as_string(&self) -> Option<Cow<'_, str>> { self.value().as_string() }
|
||||||
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { self.value().as_bytestring() }
|
fn as_bytestring(&self) -> Option<Cow<'_, [u8]>> { self.value().as_bytestring() }
|
||||||
fn as_symbol(&self) -> Option<Cow<'_, str>> { self.value().as_symbol() }
|
fn as_symbol(&self) -> Option<Cow<'_, str>> { self.value().as_symbol() }
|
||||||
fn is_record(&self) -> bool { self.value().is_record() }
|
fn is_record(&self) -> bool { self.value().is_record() }
|
||||||
fn label(&self) -> Option<&dyn Value<D>> { self.value().label() }
|
fn label(&self) -> &dyn Value<D> { self.value().label() }
|
||||||
fn is_sequence(&self) -> bool { self.value().is_sequence() }
|
fn is_sequence(&self) -> bool { self.value().is_sequence() }
|
||||||
fn len(&self) -> Option<usize> { self.value().len() }
|
fn len(&self) -> usize { self.value().len() }
|
||||||
fn index(&self, i: usize) -> &dyn Value<D> { self.value().index(i) }
|
fn index(&self, i: usize) -> &dyn Value<D> { self.value().index(i) }
|
||||||
|
fn iter(&self) -> Box<dyn Iterator<Item = &dyn Value<D>> + '_> { self.value().iter() }
|
||||||
fn is_set(&self) -> bool { self.value().is_set() }
|
fn is_set(&self) -> bool { self.value().is_set() }
|
||||||
fn has(&self, v: &dyn Value<D>) -> bool { self.value().has(v) }
|
fn has(&self, v: &dyn Value<D>) -> bool { self.value().has(v) }
|
||||||
fn is_dictionary(&self) -> bool { self.value().is_dictionary() }
|
fn is_dictionary(&self) -> bool { self.value().is_dictionary() }
|
||||||
fn get(&self, k: &dyn Value<D>) -> Option<&dyn Value<D>> { self.value().get(k) }
|
fn get(&self, k: &dyn Value<D>) -> Option<&dyn Value<D>> { self.value().get(k) }
|
||||||
fn entries(&self) -> Option<Box<dyn Iterator<Item = (&dyn Value<D>, &dyn Value<D>)> + '_>> { self.value().entries() }
|
fn entries(&self) -> Box<dyn Iterator<Item = (&dyn Value<D>, &dyn Value<D>)> + '_> { self.value().entries() }
|
||||||
fn is_embedded(&self) -> bool { self.value().is_embedded() }
|
fn is_embedded(&self) -> bool { self.value().is_embedded() }
|
||||||
fn embedded(&self) -> Option<Cow<'_, D>> { self.value().embedded() }
|
fn embedded(&self) -> Cow<'_, D> { self.value().embedded() }
|
||||||
fn annotations(&self) -> Option<&[Box<dyn Value<D>>]> { Some(&self.1) }
|
fn annotations(&self) -> Option<&[Box<dyn Value<D>>]> { Some(&self.1) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,10 +508,16 @@ mod demo {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn a() {
|
#[test] fn a() {
|
||||||
|
let l = Symbol("label");
|
||||||
|
let r = Record::new(owned::<NoValue, _>(l.clone()), vec![owned(1), owned(2), owned(3)]);
|
||||||
|
let r2 = Record::new(owned::<NoValue, _>(l), vec![owned(1), owned(2), owned(4)]);
|
||||||
|
|
||||||
let mut v: Map<Box<dyn Value<NoValue>>, String> = Map::new();
|
let mut v: Map<Box<dyn Value<NoValue>>, String> = Map::new();
|
||||||
v.insert(Box::new("abc"), "def".to_owned());
|
v.insert(Box::new("abc"), "def".to_owned());
|
||||||
v.insert(Box::new(123), "xyz".to_owned());
|
v.insert(Box::new(123), "xyz".to_owned());
|
||||||
v.insert(Box::new(vec![1, 2, 3]), "www".to_owned());
|
v.insert(Box::new(vec![1, 2, 3]), "www".to_owned());
|
||||||
|
v.insert(Box::new(r2), "bbb".to_owned());
|
||||||
|
v.insert(Box::new(r), "aaa".to_owned());
|
||||||
let w: &dyn Value<NoValue> = &v;
|
let w: &dyn Value<NoValue> = &v;
|
||||||
println!("GETw abc {:?}", w.get(&"abc"));
|
println!("GETw abc {:?}", w.get(&"abc"));
|
||||||
println!("GETw 123 {:?}", w.get(&123));
|
println!("GETw 123 {:?}", w.get(&123));
|
||||||
|
@ -465,7 +525,7 @@ mod demo {
|
||||||
println!("GETv abc {:?}", v.get(value(&"abc")));
|
println!("GETv abc {:?}", v.get(value(&"abc")));
|
||||||
println!("GETv 123 {:?}", v.get(value(&123)));
|
println!("GETv 123 {:?}", v.get(value(&123)));
|
||||||
println!("GETv qqq {:?}", v.get(value(&"qqq")));
|
println!("GETv qqq {:?}", v.get(value(&"qqq")));
|
||||||
for (kk, vv) in w.entries().unwrap() {
|
for (kk, vv) in w.entries() {
|
||||||
println!("{:?} {:?} ==> {:?} {:?}", kk.value_class(), kk, vv.value_class(), vv);
|
println!("{:?} {:?} ==> {:?} {:?}", kk.value_class(), kk, vv.value_class(), vv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue