Skip to content

Instantly share code, notes, and snippets.

Created September 23, 2016 20:40
Show Gist options
  • Save anonymous/5c527f02d99b015868f6b57275c328d7 to your computer and use it in GitHub Desktop.
Save anonymous/5c527f02d99b015868f6b57275c328d7 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
pub struct Timeline<'a> {
/// The URL to request tweets from.
link: &'static str,
/// The consumer token to authenticate requests with.
con_token: &'a auth::Token<'a>,
/// The access token to authenticate requests with.
access_token: &'a auth::Token<'a>,
/// Optional set of params to include prior to adding lifetime navigation parameters.
params_base: Option<ParamList<'a>>,
/// The maximum number of tweets to return in a single call. Twitter doesn't guarantee returning
/// exactly this number, as suspended or deleted content is removed after retrieving the initial
/// collection of tweets.
pub count: i32,
/// The largest/most recent tweet ID returned in the last call to `start`, `older`, or `newer`.
pub max_id: Option<i64>,
/// The smallest/oldest tweet ID returned in the last call to `start`, `older`, or `newer`.
pub min_id: Option<i64>,
}
impl<'a> Timeline<'a> {
/// Clear the saved IDs on this timeline.
pub fn reset(&mut self) {
self.max_id = None;
self.min_id = None;
}
/// Clear the saved IDs on this timeline, and return the most recent set of tweets.
pub fn start(&mut self) -> WebResponse<Vec<Tweet>> {
self.reset();
self.older(None)
}
/// Return the set of tweets older than the last set pulled, optionally placing a minimum tweet
/// ID to bound with.
pub fn older(&mut self, since_id: Option<i64>) -> WebResponse<Vec<Tweet>> {
let resp = try!(self.call(since_id, self.min_id.map(|id| id - 1)));
self.map_ids(&resp.response);
Ok(resp)
}
/// Return the set of tweets newer than the last set pulled, optionall placing a maximum tweet
/// ID to bound with.
pub fn newer(&mut self, max_id: Option<i64>) -> WebResponse<Vec<Tweet>> {
let resp = try!(self.call(self.max_id, max_id));
self.map_ids(&resp.response);
Ok(resp)
}
/// Return the set of tweets between the IDs given.
///
/// Note that the range is not fully inclusive; the tweet ID given by `since_id` will not be
/// returned, but the tweet ID in `max_id` will be returned.
///
/// If the range of tweets given by the IDs would return more than `self.count`, the newest set
/// of tweets will be returned.
pub fn call(&self, since_id: Option<i64>, max_id: Option<i64>) -> WebResponse<Vec<Tweet>> {
let mut params = self.params_base.as_ref().cloned().unwrap_or_default();
add_param(&mut params, "count", self.count.to_string());
if let Some(id) = since_id {
add_param(&mut params, "since_id", id.to_string());
}
if let Some(id) = max_id {
add_param(&mut params, "max_id", id.to_string());
}
let mut resp = try!(auth::get(self.link, self.con_token, self.access_token, Some(&params)));
parse_response(&mut resp)
}
/// Helper builder function to set the page size.
pub fn with_page_size(self, page_size: i32) -> Self {
Timeline { count: page_size, ..self }
}
/// With the returned slice of Tweets, set the min_id and max_id on self.
fn map_ids(&mut self, resp: &[Tweet]) {
self.max_id = resp.first().map(|status| status.id);
self.min_id = resp.last().map(|status| status.id);
}
/// Create an instance of `Timeline` with the given link and tokens.
fn new(link: &'static str,
params_base: Option<ParamList<'a>>,
con_token: &'a auth::Token,
access_token: &'a auth::Token)
-> Self {
Timeline {
link: link,
con_token: con_token,
access_token: access_token,
params_base: params_base,
count: 20,
max_id: None,
min_id: None,
}
}
}
/// From the given latitude/longitude and accuracy measurement, return up to 20 Places that can be
/// attached to a new tweet.
pub fn reverse_geocode(latitude: f64,
longitude: f64,
within: Accuracy,
granularity: Option<PlaceType>,
max_results: Option<u32>,
con_token: &auth::Token,
access_token: &auth::Token)
-> WebResponse<SearchResult> {
let mut params = HashMap::new();
add_param(&mut params, "lat", latitude.to_string());
add_param(&mut params, "long", longitude.to_string());
add_param(&mut params, "accuracy", within.to_string());
if let Some(param) = granularity {
add_param(&mut params, "granularity", param.to_string());
}
if let Some(count) = max_results {
let count = if count == 0 || count > 20 { 20 } else { count };
add_param(&mut params, "max_results", count.to_string());
}
let mut resp = try!(auth::get(links::place::REVERSE_GEOCODE,
con_token,
access_token,
Some(&params)));
parse_response(&mut resp)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment