causal-agent / ego-tree Goto Github PK
View Code? Open in Web Editor NEWVec-backed ID-tree
Home Page: https://docs.rs/ego-tree
License: ISC License
Vec-backed ID-tree
Home Page: https://docs.rs/ego-tree
License: ISC License
In a web crawler, when I strip the HTML tree, sometimes detach()
panic on the .unwrap()
.
insert_after
method uses 'before' in its docstring.
It will simplify the code a lot.
The manual indentation messes with the indentation of values debug formatted.
Calling insert_id_before
or insert_id_after
with a node that is already a child doesn't remove it from the parent's list of children.
I came across this while trying to replace a node with its children.
If this is unexpected behavior, I'd be happy to make a PR.
Reproducible example:
//! ```cargo
//! [dependencies]
//! ego-tree = "=0.6.2"
//! scraper = "=0.16.0"
//! ```
use scraper::{ElementRef, Html, Selector};
fn main() {
let html = r#"
<p> Some text that includes
<a href="Some_Page">several</a>
<a href="./Another_Page">relative links</a>
and
<a href="https://example.com/page">an absolute link</a>
.
</p>
"#;
let anchors = Selector::parse("a").unwrap();
let mut document = Html::parse_fragment(html);
let links: Vec<_> = document
.select(&anchors)
.map(|el| el.id())
.collect();
for id in links {
let Some(mut node) = document.tree.get_mut(id) else { continue };
while let Some(mut child) = node.first_child() {
let child_id = child.id();
eprintln!("Reparenting node {:?}", child_id);
child.detach(); // <---- comment this for infinite loop
node.insert_id_before(child_id);
// node.insert_id_after(child_id);
}
node.detach();
}
}
Being able to serialize the tree would be handy, and could be an optional feature gated behind a flag named serde
or something.
It will be useful if NodeRef
and NodeMut
will be able to return an underling tree (as a reference). So there will be no need to pass tree itself and a node.
What about nodes remove support? I understand that with a current architecture it's not really possible because it will invalidate NodeId
, but what if I really-really have to remove a node?
UPD: I just noticed that you rewrote the whole thing...
I'd like to insert a child into a NodeMut at a specified index. Seems like it should be easy, but I can't figure it out. Keep running into lifetime problems.
My non-working code is:
fn insert_child_at_index<'a, T>(parent: &'a mut NodeMut<'a, T>, value: T, index: usize) -> NodeMut<'a, T> {
if let Some(insert_before_id) = parent.tree.get(parent.id).unwrap().children().skip(index).next().map(|n| n.id) {
parent.tree.get_mut(insert_before_id).unwrap().insert_before(value)
} else {
parent.append(value)
}
}
The logic (for now) is to insert before child node at given index if child node exists, otherwise insert at end. In final API it probably makes more sense to throw error if index is beyond count, but I'm trying to keep example code simple as possible at moment.
Any tips on how to get this working?
let mut tree = tree! {
'a' => {
'b',
'c' => { 'd', 'e' },
}
};
let c_id = tree.root().last_child().unwrap().id();
unsafe { tree.root_mut().reparent_from_id_append(c_id); }
println!("tree now {:?}", tree);
Can we append a tree as a subtree of another tree?
Maybe, from the API perspective, it will be better to allow get(_mut)
to return Option
therefore making them safe, just like the Vec
itself. Accessing the vector by the index isn't unsafe, so I don't see a point in making it that way.
You can keep such functionality under the get(_mut)_unchecked
methods.
The problem is that I'm using NodeId extensively for nodes cycles and it forces me to fill my code with an unnecessary unsafe
. And since Tree
is mostly immutable all those id's will be valid anyway.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.