Coder Social home page Coder Social logo

ego-tree's People

Contributors

bright-star avatar causal-agent avatar razrfalcon avatar simonsapin avatar yoursvivek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ego-tree's Issues

`insert_id_before` doesn't detach the inserted node

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();
    }
}

Serde derive support?

Being able to serialize the tree would be handy, and could be an optional feature gated behind a flag named serde or something.

What about tree() method?

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.

Remove support?

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...

What about dropping the unsafe?

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.

How to insert child at index?

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.