diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 77 |
1 files changed, 76 insertions, 1 deletions
diff --git a/src/lib.rs b/src/lib.rs index df7eead..18836d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ use core::fmt; +use query::{parse_query, QueryComponent, QueryElement, QueryParseError}; use tag::Tag; mod query; @@ -25,10 +26,84 @@ impl Html { } } - pub fn query<S: AsRef<str>>(&self, query: S) -> Option<&Node> { + pub fn query<S: AsRef<str>>(&self, query: S) -> Result<Option<&Node>, QueryParseError> { + let query = parse_query(query.as_ref())?; + + let mut working: Vec<&Node> = self.nodes.iter().collect(); + + for component in &query { + let component_working: Vec<&Node> = std::mem::take(&mut working); + for node in component_working { + match component { + QueryComponent::DirectElement(direct) => { + if Self::node_matches(node, direct) { + working.push(node); + } + } + QueryComponent::Element(element) => { + // GENNY: + // you were working on the query system. This one needs to recur, + // checking the current component against the entire depth of + // children of the node. I'm worried about lifetimes here. For + // immutable we might be alright but what happens when we're + // muteable and we want to return a parent and it's child because + // they both match? + // + // Don't get discouraged; it's a hard problem. Perhaps we write an + // iterator so we don't have to keep references around? Sticking + // everything in an Rc or whatever structure I'd need feels icky. + // + // Perhaps it's the way I'm searching. I could recur through the + // current node, from self.nodes, until match failure. It fits + // the funciton signature, returning one Node, but perhaps doesn't + // fit the purpose. + // + // But the purpose is to easily insert parsed text into HTML + // without templating it, so maybe it is fit for purpose. That + // only needs to find one element at a time perhaps. + // + // All goes sour maybe I can return IDs to nodes? Keep a counter + // in HTML where each node gets an increasing ID. Pass the ID to + // a funtion in HTML for modification. Or maybe have IDs, + // NodeHandles let's call them, contain an Rc<RefCell<Html>>. + // + // That is by far enough thinking for the night. It's time to + // head to bed. <3 i love you + todo!() + } + } + } + } + todo!() } + fn node_matches(node: &Node, component: &QueryElement) -> bool { + if let Node::Tag(tag) = node { + if let Some(comp_name) = component.tag.as_deref() { + if comp_name != tag.name { + return false; + } + } + + match (tag.id(), component.id.as_deref()) { + (None, Some(_)) => return false, + (Some(tag_id), Some(comp_id)) if tag_id != comp_id => return false, + _ => (), + } + + if let Some(comp_class) = component.class.as_deref() { + if !tag.has_class(comp_class) { + return false; + } + } + + true + } else { + false + } + } + fn parse_node(raw: &str) -> Consumed { match Self::is_tag(raw) { Some(_) => { |