Last active
May 3, 2021 13:37
-
-
Save jdm/9900569 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Node { | |
shared_ptr<Node> parent; | |
shared_ptr<Node> first_child; | |
TextNode* as_text_node() { assert(/*sensible check*/); return (TextNode*)this; } | |
virtual Element* as_element() { return NULL; } | |
}; | |
struct TextNode: public Node { | |
}; | |
struct Element: public Node { | |
vector<string, string> attrs; | |
void set_attribute(const string& key, const string& value); | |
virtual void before_set_attr(const string& key, const string& value); | |
virtual void after_set_attr(const string& key, const string& value); | |
virtual Element* as_element() { return this; } | |
}; | |
void Element::set_attribute(const string& key, const string& value) | |
{ | |
before_set_attr(key, value); | |
//...update attrs... | |
after_set_attr(key, value); | |
} | |
struct HTMLImageElement: public Element { | |
virtual void before_set_attr(const string& key, const string& value); | |
}; | |
void HTMLImageElement::before_set_attr(const string& key, const string& value) | |
{ | |
if (key == "src") { | |
//..remove cached image with url |value|... | |
} | |
Element::before_set_attr(key, value); | |
} | |
struct HTMLVideoElement: public Element { | |
bool cross_origin; | |
void after_set_attr(const string& key, const string& value); | |
}; | |
void HTMLVideoElement::after_set_attr(const string& key, const string& value) | |
{ | |
if (key == "crossOrigin") { | |
cross_origin = value == "true"; | |
} | |
Element::after_set_attr(key, value); | |
} | |
void process_any_element(Element* element) { | |
//... | |
} | |
shared_ptr<HTMLVideoElement> videoElement = ...; | |
process_any_element(videoElement); | |
shared_ptr<Node> node = videoElement->first_child; | |
shared_ptr<Element> element = node->as_element(); | |
if (!element) { | |
shared_ptr<TextNode> text = node->as_text_node(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
While trying to translate this into rust+rust-lang/rfcs/#9, I noticed an error in this part:
If
node
is an Element, then the local variableelement
is created as a newshared_ptr
that thinks it has sole ownership of it--it is not sharing withnode
. Soelement
andnode
will both try to free the same object when they go out of scope, and if one outlive the other you could access an already-destroyed object through the longer-lived one. Same problem fortext
.This would still compile fine in C++, of course, which illustrates why we all want Rust. The proposals for modeling the DOM in rust may look different, but none of them would let something like that compile.
I think this is what you want:
where
element
andtext
would be borrowed pointers in translated rust versions. Do I have this right?