0

I'm using the twitter_stream crate to pull data from Twitter. The API supports filtering the data by some parameter; in my case I am trying to filter using a bounding box location. The library takes an Option<((f64, f64), (f64, f64))>, so I create a tuple in that form:

let bounds = ((0.59 as f64, 0.59 as f64), (0.59 as f64, 0.59 as f64));

When I do Some(bounds) to wrap this in an Option, I appear to end up with the type Option<&[((f64, f64), (f64, f64))]>

This adds a &[] around my tuple, and I don't understand what that means or why it's there. My best guess is it means that there's now a borrowed array with one element around the tuple, but I don't understand why there would be an array, and I tried adding .to_owned() everywhere and it didn't change a thing, so I feel like I am way off base.

Code:

extern crate twitter_stream;

use twitter_stream::rt::{self, Future, Stream};
use twitter_stream::{Token, TwitterStreamBuilder};

fn main() {
    let bounds = ((0.59 as f64, 0.59 as f64), (0.59 as f64, 0.59 as f64));
    let future = TwitterStreamBuilder::filter(Token::new(
        "consumer_key",
        "consumer_secret",
        "access_token",
        "access_secret",
    ))
    .locations(Some(bounds))
    .listen()
    .unwrap()
    .flatten_stream()
    .for_each(|json| {
        println!("{}", json);
        Ok(())
    })
    .map_err(|e| println!("error: {}", e));

    rt::run(future);
}

Error:

error[E0277]: the trait bound `std::option::Option<&[((f64, f64), (f64, f64))]>: std::convert::From<std::option::Option<((f64, f64), (f64, f64))>>` is not satisfied
 --> src/main.rs:9:14                                                                                                  
  |                                                                                                                    
9 |             .locations(Some(bounds))                                                                               
  |              ^^^^^^^^^ the trait `std::convert::From<std::option::Option<((f64, f64), (f64, f64))>>` is not implemented for `std::option::Option<&[((f64, f64), (f64, f64))]>`
  |                                                                                                                    
  = help: the following implementations were found:                                                                    
            <std::option::Option<&'a T> as std::convert::From<&'a std::option::Option<T>>>                             
            <std::option::Option<&'a mut T> as std::convert::From<&'a mut std::option::Option<T>>>                     
            <std::option::Option<T> as std::convert::From<T>>                                                          
  = note: required because of the requirements on the impl of `std::convert::Into<std::option::Option<&[((f64, f64), (f64, f64))]>>` for `std::option::Option<((f64, f64), (f64, f64))>`
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Sasha Kondrashov
  • 4,038
  • 1
  • 18
  • 29
  • 2
    It's the other way around: you still have a tuple, but `locations` wants something else: [docs](https://docs.rs/twitter-stream/0.9.0/twitter_stream/struct.TwitterStreamBuilder.html#method.locations) – Michail Mar 23 '19 at 20:20
  • I made a mistake when editing my code to a reproducible example - now it's the right error – Sasha Kondrashov Mar 23 '19 at 20:46
  • but you are right, it is still the other way around. crap I'll have to think again about it – Sasha Kondrashov Mar 23 '19 at 20:48
  • 1
    I didn't test it, but you should be able to drop `Some` wrapping and just pass `locations` a reference to a single-element array. There's a blanket `impl From for Option`, so a simple reference to a slice should be accepted by `locations`. – Michail Mar 23 '19 at 20:56
  • just figured out that it takes a slice, not an array. so where bounds is my tuple: &[bounds][..] gave me what I wanted, and I could drop the Some() like you said – Sasha Kondrashov Mar 23 '19 at 21:08
  • I really need to be more careful with terminology, 'array' was a very bad choice here. Glad to know it didn't cause much trouble. – Michail Mar 23 '19 at 21:16

1 Answers1

2

You are reading the error message backwards. Cleaned up a bit, it says:

the trait bound Option<&[BoundingBox]>: From<Option<BoundingBox>> is not satisfied

That is, it's not possible to create an &[BoundingBox] from a BoundingBox.

The locations method is defined as:

pub fn locations(
    &mut self, 
    locations: impl Into<Option<&'a [BoundingBox]>>
) -> &mut Self

That is, it takes any type that can be converted into an Option of a slice of coordinate boxes. You are attempting to provide just an Option of a single coordinate box.

Instead, create an array of one value and create a slice:

.locations(Some(&[bounds][..]))

Or

.locations(Some(std::slice::from_ref(&bounds)))

You can also make use of the fact that Option<T> implements From<T>:

.locations(&[bounds][..])

Or

.locations(std::slice::from_ref(&bounds))

See also:


For readability, I'm pretending that this type alias exists:

type BoundingBox = ((f64, f64), (f64, f64));
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366