Skip to content

Commit

Permalink
Merge pull request #698 from Adam-Vandervorst/main
Browse files Browse the repository at this point in the history
New standard lib operations: union, intersection, subtraction, and unique
  • Loading branch information
vsbogd authored Jun 5, 2024
2 parents 06e30fa + 37b4a59 commit 3dd92c7
Show file tree
Hide file tree
Showing 6 changed files with 429 additions and 23 deletions.
34 changes: 34 additions & 0 deletions lib/src/atom/serial.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::hash::{DefaultHasher, Hasher};

/// Serial module defines an API to implement serialization/deserialization of the
/// grounded atoms. The serialization API can be used for saving grounded atoms to
/// disk, sending them over network or implement value conversion between
Expand All @@ -23,6 +25,8 @@ pub trait Serializer {
fn serialize_i64(&mut self, _v: i64) -> Result { Err(Error::NotSupported) }
/// Serialize f64 value.
fn serialize_f64(&mut self, _v: f64) -> Result { Err(Error::NotSupported) }
/// Serialize string value.
fn serialize_str(&mut self, _v: &str) -> Result { Err(Error::NotSupported) }
}

/// Serialization error code
Expand All @@ -31,5 +35,35 @@ pub enum Error {
NotSupported,
}

/// Serializer which converts serialized atom into native Rust type T.
pub trait ConvertingSerializer<T>: Serializer {
fn as_mut(&mut self) -> &mut dyn Serializer;
fn into_type(self) -> Option<T>;
}

/// Serialization result type
pub type Result = std::result::Result<(), Error>;

// there are much speedier hashers, but not sure if it's worth the extra dependency given the other options
impl Serializer for DefaultHasher {
fn serialize_bool(&mut self, v: bool) -> Result { Ok(self.write_u8(v as u8)) }
fn serialize_i64(&mut self, v: i64) -> Result { Ok(self.write_i64(v)) }
fn serialize_f64(&mut self, v: f64) -> Result { Ok(self.write_u64(v as u64)) }
fn serialize_str(&mut self, v: &str) -> Result { Ok(v.bytes().for_each(|b| self.write_u8(b))) }
}

// for debugging
impl Serializer for String {
fn serialize_bool(&mut self, v: bool) -> Result { Ok(self.push_str(&*v.to_string())) }
fn serialize_i64(&mut self, v: i64) -> Result { Ok(self.push_str(&*v.to_string())) }
fn serialize_f64(&mut self, v: f64) -> Result { Ok(self.push_str(&*v.to_string())) }
fn serialize_str(&mut self, v: &str) -> Result { Ok(self.push_str(v)) }
}

// for speed, but is technically unsafe at usage site because not a valid utf-8 string
impl Serializer for Vec<u8> {
fn serialize_bool(&mut self, v: bool) -> Result { Ok(self.push(v as u8)) }
fn serialize_i64(&mut self, v: i64) -> Result { Ok(self.extend(v.to_le_bytes())) }
fn serialize_f64(&mut self, v: f64) -> Result { Ok(self.extend(v.to_le_bytes())) }
fn serialize_str(&mut self, v: &str) -> Result { Ok(self.extend(v.bytes())) }
}
11 changes: 3 additions & 8 deletions lib/src/metta/runner/arithmetics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ impl<'a> AsPrimitive<'a> {
std::convert::TryInto::<&dyn super::GroundedAtom>::try_into(self.atom).ok()
}

fn as_type<T: 'static + Clone, S: ConvertingSerializer<T>>(&self, mut serializer: S) -> Option<T> {
fn as_type<T: 'static + Clone, S: serial::ConvertingSerializer<T>>(&self, mut serializer: S) -> Option<T> {
self.as_gnd()
.map(|gnd| {
gnd.as_any_ref()
Expand All @@ -377,12 +377,7 @@ impl<'a> AsPrimitive<'a> {
}
}

trait ConvertingSerializer<T>: serial::Serializer {
fn as_mut(&mut self) -> &mut dyn serial::Serializer;
fn into_type(self) -> Option<T>;
}

impl ConvertingSerializer<Bool> for BoolSerializer {
impl serial::ConvertingSerializer<Bool> for BoolSerializer {
fn as_mut(&mut self) -> &mut dyn serial::Serializer {
self
}
Expand All @@ -391,7 +386,7 @@ impl ConvertingSerializer<Bool> for BoolSerializer {
}
}

impl ConvertingSerializer<Number> for NumberSerializer {
impl serial::ConvertingSerializer<Number> for NumberSerializer {
fn as_mut(&mut self) -> &mut dyn serial::Serializer {
self
}
Expand Down
Loading

0 comments on commit 3dd92c7

Please sign in to comment.