use eko_gc::{Gc, GcArena, GcRefCell, Trace}; #[derive(Debug)] pub struct RefNamedObject<'n> { pub name: &'n str, } unsafe impl<'a> Trace for RefNamedObject<'a> { unsafe fn mark(&self) {} unsafe fn root(&self) {} unsafe fn unroot(&self) {} } #[derive(Debug)] pub struct NamedObject { pub name: String, } unsafe impl Trace for NamedObject { unsafe fn mark(&self) {} unsafe fn root(&self) {} unsafe fn unroot(&self) {} } #[derive(Debug)] pub struct CircularNamedObject<'a> { pub name: String, pub other: Option>>>, } unsafe impl<'a> Trace for CircularNamedObject<'a> { unsafe fn mark(&self) { self.other.mark(); } unsafe fn root(&self) { self.other.root(); } unsafe fn unroot(&self) { self.other.unroot(); } } #[derive(Debug)] pub struct TreeNode<'a> { pub parent: Option>>>, pub children: Vec>>>, } unsafe impl<'a> Trace for TreeNode<'a> { unsafe fn mark(&self) { self.parent.mark(); self.children.mark(); } unsafe fn root(&self) { self.parent.root(); self.children.root(); } unsafe fn unroot(&self) { self.parent.unroot(); self.children.unroot(); } } #[test] fn gc_simple() { let arena: GcArena = GcArena::new(); arena.alloc(String::from("foo")); } #[test] fn gc() { let arena: GcArena = GcArena::new(); let n1: Gc; { let n2: Gc = arena.alloc(NamedObject { name: String::from("Hello, World!"), }); n1 = Gc::clone(&n2); } assert_eq!(n1.name, String::from("Hello, World!")); } #[test] fn gc_ref() { let a: String = String::from("Hello, World!"); { let arena: GcArena = GcArena::new(); let n: Gc = arena.alloc(RefNamedObject { name: &a }); assert_eq!(n.name, String::from("Hello, World!")); } } #[test] fn gc_circular() { let arena: GcArena = GcArena::new(); let n1 = arena.alloc(GcRefCell::new(CircularNamedObject { name: String::from("n1"), other: None, })); let n2 = arena.alloc(GcRefCell::new(CircularNamedObject { name: String::from("n2"), other: None, })); n1.borrow_mut().other = Some(Gc::clone(&n2)); n2.borrow_mut().other = Some(Gc::clone(&n1)); } #[test] fn gc_tree() { let arena: GcArena = GcArena::new(); // Create nodes let root = arena.alloc(GcRefCell::new(TreeNode { parent: None, children: Vec::new(), })); let child1 = arena.alloc(GcRefCell::new(TreeNode { parent: None, children: Vec::new(), })); let child2 = arena.alloc(GcRefCell::new(TreeNode { parent: None, children: Vec::new(), })); // Add first child root.borrow_mut().children.push(Gc::clone(&child1)); child1.borrow_mut().parent = Some(Gc::clone(&root)); // Add second child root.borrow_mut().children.push(Gc::clone(&child2)); child2.borrow_mut().parent = Some(Gc::clone(&root)); }