Skip to content

Instantly share code, notes, and snippets.

@jdm
Last active December 25, 2015 21:48
Show Gist options
  • Save jdm/7044664 to your computer and use it in GitHub Desktop.
Save jdm/7044664 to your computer and use it in GitHub Desktop.
use std::unstable::raw::Box;
use std::cast;
struct Unreflected<T> {
priv unreflected: T
}
trait EagerReflector {
fn init_reflector(self) -> Self;
}
impl<T: EagerReflector> Unreflected<T> {
pub fn usable(self) -> T {
self.unreflected.init_reflector()
}
pub fn new(val: T) -> Unreflected<T> {
Unreflected {
unreflected: val
}
}
}
trait Reflectable {
fn reflector<'a>(&'a self) -> &'a Reflector;
}
struct Reflector {
js_object: Option<int>
}
impl Reflector {
fn new() -> Reflector {
Reflector {
js_object: None
}
}
}
struct DOMParser {
reflector_: Reflector
}
impl Reflectable for DOMParser {
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
}
impl EagerReflector for @mut DOMParser {
fn init_reflector(self) -> @mut DOMParser{
self.reflector_.js_object = Some(1);
self
}
}
impl DOMParser {
fn new() -> Unreflected<@mut DOMParser> {
let parser = @mut DOMParser {
reflector_: Reflector::new()
};
Unreflected::new(parser)
}
}
struct AbstractNode {
node: *mut Box<Node>
}
struct Node {
reflector_: Reflector
}
impl Reflectable for Node {
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
}
impl Reflectable for AbstractNode {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.node().reflector()
}
}
impl EagerReflector for AbstractNode {
fn init_reflector(self) -> AbstractNode {
self.mut_node().reflector_.js_object = Some(2);
self
}
}
impl Node {
fn new() -> Unreflected<AbstractNode> {
let node = @mut Node {
reflector_: Reflector::new()
};
AbstractNode::as_abstract_node(node)
}
}
impl AbstractNode {
fn as_abstract_node(node: @mut Node) -> Unreflected<AbstractNode> {
let abstract = AbstractNode {
node: unsafe { cast::transmute(node) }
};
Unreflected::new(abstract)
}
fn node<'a>(&self) -> &'a Node {
unsafe { &(*self.node).data }
}
fn mut_node<'a>(&self) -> &'a mut Node {
unsafe { &mut (*self.node).data }
}
}
fn main() {
let parser = DOMParser::new().usable();
assert!(parser.reflector().js_object.is_some());
let node = Node::new().usable();
assert!(node.reflector().js_object.is_some());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment