~raph/immutable

38be5a6ece426c903bb2474c6627ebd0f5d8d37e — Raph Levien 2 years ago 8d98f25 master
More development of proxy objects
2 files changed, 39 insertions(+), 4 deletions(-)

M src/proxy.rs
M src/value.rs
M src/proxy.rs => src/proxy.rs +27 -4
@@ 21,6 21,14 @@ pub struct ProxyInner<'a> {
}

impl Proxy {
    pub fn new(value: &Value) -> Proxy {
        Proxy {
            original: value.clone(),
            new: value.clone(),
            delta: Vec::new(),
        }
    }

    pub fn root(&mut self) -> ProxyInner {
        ProxyInner {
            proxy: self,


@@ 79,9 87,9 @@ impl<'a> ProxyInner<'a> {

    /// Update a key in a map to an optional new value (or delete the key).
    // Maybe use typestate pattern, can't fail if it's a map?
    pub fn update(&mut self, key: String, value: Option<Value>) -> Result<(), Error> {
    pub fn update(&mut self, key: impl Into<String>, value: Option<Value>) -> Result<(), Error> {
        let mut path = self.path.clone();
        path.push(key.into());
        path.push(key.into().into());
        let delta_el = DeltaEl {
            path,
            new_value: value,


@@ 90,14 98,14 @@ impl<'a> ProxyInner<'a> {
    }

    /// Update a key in a map to a new value.
    pub fn insert(&mut self, key: String, value: Value) -> Result<(), Error> {
    pub fn insert(&mut self, key: impl Into<String>, value: Value) -> Result<(), Error> {
        self.update(key, Some(value))
    }

    /// Delete a key in a map.
    ///
    /// TODO: should we return an error if the key doesn't exist?
    pub fn delete(&mut self, key: String) -> Result<(), Error> {
    pub fn delete(&mut self, key: impl Into<String>) -> Result<(), Error> {
        self.update(key, None)
    }



@@ 114,3 122,18 @@ impl<'a> ProxyInner<'a> {
        self.proxy.apply_delta_el(delta_el)
    }
}

mod tests {
    use super::*;

    #[test]
    fn proxy_simple() {
        let empty = Value::empty_map();
        let mut proxy = Proxy::new(&empty);
        let mut root = proxy.root();
        let _ = root.insert("foo", "bar".to_string().into());
        let delta = proxy.into_delta();
        let new = empty.apply(&delta).unwrap();
        assert_eq!(new.as_map().unwrap().get("foo").unwrap().as_str(), Some("bar"));
    }
}
\ No newline at end of file

M src/value.rs => src/value.rs +12 -0
@@ 168,6 168,10 @@ impl Value {
            None
        }
    }

    pub fn empty_map() -> Value {
        HashMap::new().into()
    }
}

impl From<String> for Value {


@@ 176,6 180,14 @@ impl From<String> for Value {
    }
}

impl From<&str> for Value {
    fn from(s: &str) -> Value {
        Value(Arc::new(ValueEnum::String(s.into())))
    }
}

// add Cow<str> etc?

impl From<f64> for Value {
    fn from(f: f64) -> Value {
        Value(Arc::new(ValueEnum::Float(f)))