Aidoku / aidoku-rs

Aidoku source bindings in Rust
25 stars 8 forks source link

Node Dropped After `filter_map` #8

Open aphronyx opened 10 months ago

aphronyx commented 10 months ago

code:

let arr = manga_page.select("p.data:contains(作者:) > a").array();

arr.clone()
    .filter_map(|value| value.as_node().ok())
    .for_each(|node| println!("fm:{}", node.outer_html().read()));

for value in arr {
    let Some(node) = value.as_node().ok() else {
        continue;
    };
    println!("for:{}", node.outer_html().read());
}

output:

fm:
fm:
for:<a href="/home/index/search/?keyword=탄몬">탄몬</a>
for:<a href="/home/index/search/?keyword=쨈닭맨">쨈닭맨</a>
Skittyblock commented 10 months ago

I'm guessing this might have been fixed with https://github.com/Aidoku/Aidoku/commit/b1e18edbf8373d55068663c98a0ee374c6a14c98 (something I intended to do a long time ago), but you can wait until that's in the public build to test and see.

aphronyx commented 10 months ago

I'm guessing this might have been fixed with Aidoku/Aidoku@b1e18ed (something I intended to do a long time ago), but you can wait until that's in the public build to test and see.

the source Skittyblock/aidoku-community-sources#434 was written and tested with Aidoku/Aidoku@99d2907, and the #4 had been fixed, but this issue (filter_map) still happens to me, so i don’t think it has to do with reference issue

Skittyblock commented 10 months ago

alright, I'll look into it further.

Skittyblock commented 10 months ago

Found the issue; it is indeed aidoku-rs's fault. The ValueRef is being dropped as it goes out of scope even though it's casted to a Node in as_node(). aidoku-rs should transfer ownership to the Node it returns and ignore the dropping of the ValueRef, since it also destroy's the Node's descriptor. The following code works:

arr.clone()
    .filter_map(|mut value| {
        value.1 = false;
        if value.kind() == aidoku::std::Kind::Node {
            Some(unsafe { aidoku::std::html::Node::from(value.0) })
        } else {
            None
        }
    })
    .for_each(|node| println!("fm:{}", node.outer_html().read()));