lang-extension 1.3.0

Rust Lang Extension
Documentation
use std::sync::Arc;

use super::*;

#[derive(PartialEq, Debug, Clone)]
pub struct ImmutableValue {
    value: Arc<Box<dyn Value>>,
}

impl ImmutableValue {
    pub fn new<T: Value>(value: T) -> ImmutableValue {
        Self::wrap(Value::to_boxed(value))
    }

    pub fn wrap(value: Box<dyn Value>) -> Self {
        ImmutableValue {
            value: Arc::new(value),
        }
    }

    pub fn raw_boxed(&self) -> Box<dyn Value> {
        self.value.as_ref().clone()
    }
}

unsafe impl Send for ImmutableValue {}

unsafe impl Sync for ImmutableValue {}

#[derive(Hash, PartialEq, Eq, Debug, Clone)]
pub struct ImmutableKey {
    key: Arc<Box<dyn Key>>,
}

impl ImmutableKey {
    pub fn new<T: Key>(value: T) -> ImmutableKey {
        Self::wrap(Key::to_boxed(value))
    }

    pub fn wrap(value: Box<dyn Key>) -> Self {
        ImmutableKey {
            key: Arc::new(value),
        }
    }

    pub fn raw_boxed(&self) -> Box<dyn Key> {
        self.key.as_ref().clone()
    }
}

unsafe impl Send for ImmutableKey {}

unsafe impl Sync for ImmutableKey {}

#[cfg(test)]
mod tests {
    use super::*;
    use std::collections::hash_map::DefaultHasher;
    use std::hash::{Hash, Hasher};
    use std::thread;

    #[test]
    fn immutable_value() {
        assert_eq!(ImmutableValue::new("value"), ImmutableValue::new("value"));
        assert_ne!(ImmutableValue::new("value"), ImmutableValue::new("value2"));

        println!("{:?}", ImmutableValue::new("value"));

        let v = ImmutableValue::new("value");
        assert_eq!(&v, &v.clone());

        let b: Box<dyn Value> = Box::new("value");
        assert_eq!(
            ImmutableValue::new("value"),
            ImmutableValue::wrap(b.clone())
        );

        assert_eq!(&b, &v.raw_boxed());

        let clone = v.clone();
        let handle = thread::spawn(move || {
            println!("data: {:?}", clone);
        });
        handle.join().unwrap();
    }

    #[test]
    fn immutable_key() {
        assert_eq!(ImmutableKey::new("key"), ImmutableKey::new("key"));
        assert_ne!(ImmutableKey::new("key"), ImmutableKey::new("key2"));

        println!("{:?}", ImmutableKey::new("key"));

        let k = ImmutableKey::new("key");
        assert_eq!(&k, &k.clone());

        let b: Box<dyn Key> = Box::new("key");
        assert_eq!(ImmutableKey::new("key"), ImmutableKey::wrap(b.clone()));

        assert_eq!(&b, &k.raw_boxed());

        let clone = k.clone();
        let handle = thread::spawn(move || {
            println!("data: {:?}", clone);
        });
        handle.join().unwrap();

        let mut hasher = DefaultHasher::new();
        k.hash(&mut hasher);
        let _ = hasher.finish();
    }
}