rust-syndication / rss

Library for serializing the RSS web content syndication format
https://crates.io/crates/rss
Apache License 2.0
419 stars 52 forks source link

Consume Channel and return the owned Vector of Items #68

Closed alatiera closed 6 years ago

alatiera commented 6 years ago

This allows to consume the Channel and get the owned vector/slice of Items. This can avoid the reallocation/clone of the whole Items slice in situations where you need to pass the ownership of the data, like when using futures.

For example the compiler rightfully complains when trying to do the following:

extern crate rss;
extern crate futures;

use futures::prelude::*;
use futures::stream;

use rss::{Item, Channel};
use std::error::Error;

struct Foo;

fn foo(_item: &Item) -> Box<Future<Item = Foo, Error = Box<Error>>> {
    unimplemented!()
}

fn bar(channel: Channel) -> Box<Future<Item = Vec<Foo>, Error = Box<Error>>> {
    let stream = stream::iter_ok::<_, Box<Error>>(channel.items());
    let results = stream.and_then(|item| foo(item)).collect();
    Box::new(results)
}

fn main() {}

Since you can only get a reference to an Item the compiler can't guarantee that it will satisfy the 'static lifetime requirement.

error[E0597]: `channel` does not live long enough
  --> src/main.rs:17:51
   |
17 |     let stream = stream::iter_ok::<_, Box<Error>>(channel.items());
   |                                                   ^^^^^^^ borrowed value does not live long enough
...
20 | }
   | - borrowed value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...

error: aborting due to previous error

error: Could not compile `foo`.

A way to get the above example to compile is make the signature of fn bar the following:

fn bar<'a>(channel: &'a Channel) -> Box<Future<Item = Vec<Foo>, Error = Box<Error>> + 'a > {

But that only moves the ownership problem in a higher part of the code, since you can never guarantee that channel will live until the Future is resolved.

frewsxcv commented 6 years ago

bors r+

Hope you don't mind that I renamed the method! I think the into_* convention is a little more common for methods that consume self

alatiera commented 6 years ago

No not at all, I actually could not think of anything better at the time. Thanks for fixing it!

bors[bot] commented 6 years ago

Build failed

frewsxcv commented 6 years ago

bors r+

bors[bot] commented 6 years ago

Build failed

frewsxcv commented 6 years ago

bors r+

bors[bot] commented 6 years ago

Build succeeded