Commits

Dan Connolly committed b9001b9 Draft

toward E money example in rust: sealing seems to work

Comments (0)

Files changed (1)

-# http://dl.rust-lang.org/doc/0.4/tutorial.html#getting-started
+// http://dl.rust-lang.org/doc/0.4/tutorial.html#getting-started
+
+// http://www.madmode.com/2011/11/capability-security-in-e-coffescript.html
+// http://gitorious.org/repo-roscidus/e-core/blobs/fdf9643e419eea182b4d8d983f5b9955c7b73967/src/jsrc/org/erights/e/elib/sealing/SealedBox.java
+
+use cmp::{Eq};
+
+mod sealing {
+    pub struct Brand {
+        hint: ~str
+    }
+    impl @Brand: Eq {
+        pure fn eq(other: &@Brand) -> bool { box::ptr_eq(self, *other) }
+        pure fn ne(other: &@Brand) -> bool { !box::ptr_eq(self, *other) }
+    }
+
+    pub pure fn mkBrandPair<T>(hint: ~str) -> (@Sealer<T>, @Unsealer<T>) {
+        let brand = @Brand{ hint: copy hint };
+        let sealer = @SealerImpl{brand: brand};
+        let unsealer = @UnsealerImpl{brand: brand};
+        (sealer as @Sealer<T>, unsealer as @Unsealer<T>)
+    }
+    
+    pub struct SealedBox<T: Copy> {
+        priv contents: T,
+        brand: @Brand
+    }
+
+    impl<T: Copy> SealedBox<T>: ToStr {
+        pure fn to_str() -> ~str { ~"<sealed by " + self.brand.hint + ~">" }
+    }
+
+    pub trait Sealer<T: Copy> {
+        pure fn seal(it: T) -> @SealedBox<T>;
+        pure fn getBrand() -> @Brand;
+    }
+
+    pub impl<T: Copy> Sealer<T> : ToStr {
+        pure fn to_str() -> ~str {
+            ~"<sealer for " + self.getBrand().hint + ~">"
+        }
+    }
+
+
+    struct SealerImpl { brand: @Brand }
+    impl<T: Copy> SealerImpl: Sealer<T> {
+        pure fn seal(it: T) -> @SealedBox<T> {
+            @SealedBox{contents: it, brand: self.brand }
+        }
+        pure fn getBrand() -> @Brand { self.brand }
+    }
+
+    pub trait Unsealer<T: Copy> {
+        fn unseal(box: @SealedBox<T>) -> Option<T>;  // todo: consider Result
+    }
+
+    struct UnsealerImpl { brand: @Brand }
+    impl<T: Copy> UnsealerImpl: Unsealer<T> {
+        fn unseal(box: @SealedBox<T>) -> Option<T> {
+            if (self.brand == box.brand) { Some(box.contents) }
+            else { 
+                // TODO: throw new UnsealingException("" + this + " can't unseal " + box);
+                None
+            }
+        }
+    }
+
+}
+
 fn main() {
-    io::println("hello? yes, this is rust");
+    let (s, u) = sealing::mkBrandPair(~"bob");
+    let sekret = 42;
+    match u.unseal(s.seal(sekret)) {
+      Some(i) => io::println(~"seal, unseal: " + i.to_str()),
+      None => io::println("lose!")
+    }
 }