Add min_id to pagination params
also switches to using serde_qs instead of manually serializing the query string
This commit is contained in:
@@ -17,6 +17,7 @@ serde = "1"
|
|||||||
serde_derive = "1"
|
serde_derive = "1"
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
serde_urlencoded = "0.5.3"
|
serde_urlencoded = "0.5.3"
|
||||||
|
serde_qs = "0.4.5"
|
||||||
url = "1"
|
url = "1"
|
||||||
tap-reader = "1"
|
tap-reader = "1"
|
||||||
try_from = "0.3.2"
|
try_from = "0.3.2"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use envy::Error as EnvyError;
|
|||||||
use hyper_old_types::Error as HeaderParseError;
|
use hyper_old_types::Error as HeaderParseError;
|
||||||
use reqwest::{header::ToStrError as HeaderStrError, Error as HttpError, StatusCode};
|
use reqwest::{header::ToStrError as HeaderStrError, Error as HttpError, StatusCode};
|
||||||
use serde_json::Error as SerdeError;
|
use serde_json::Error as SerdeError;
|
||||||
|
use serde_qs::Error as SerdeQsError;
|
||||||
use serde_urlencoded::ser::Error as UrlEncodedError;
|
use serde_urlencoded::ser::Error as UrlEncodedError;
|
||||||
#[cfg(feature = "toml")]
|
#[cfg(feature = "toml")]
|
||||||
use tomlcrate::de::Error as TomlDeError;
|
use tomlcrate::de::Error as TomlDeError;
|
||||||
@@ -57,6 +58,8 @@ pub enum Error {
|
|||||||
#[cfg(feature = "env")]
|
#[cfg(feature = "env")]
|
||||||
/// Error deserializing from the environment
|
/// Error deserializing from the environment
|
||||||
Envy(EnvyError),
|
Envy(EnvyError),
|
||||||
|
/// Error serializing to a query string
|
||||||
|
SerdeQs(SerdeQsError),
|
||||||
/// Other errors
|
/// Other errors
|
||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
@@ -96,6 +99,7 @@ impl error::Error for Error {
|
|||||||
Error::HeaderParseError(ref e) => e.description(),
|
Error::HeaderParseError(ref e) => e.description(),
|
||||||
#[cfg(feature = "env")]
|
#[cfg(feature = "env")]
|
||||||
Error::Envy(ref e) => e.description(),
|
Error::Envy(ref e) => e.description(),
|
||||||
|
Error::SerdeQs(ref e) => e.description(),
|
||||||
Error::Other(ref e) => e,
|
Error::Other(ref e) => e,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,6 +140,7 @@ from! {
|
|||||||
HeaderStrError, HeaderStrError,
|
HeaderStrError, HeaderStrError,
|
||||||
HeaderParseError, HeaderParseError,
|
HeaderParseError, HeaderParseError,
|
||||||
#[cfg(feature = "env")] EnvyError, Envy,
|
#[cfg(feature = "env")] EnvyError, Envy,
|
||||||
|
SerdeQsError, SerdeQs,
|
||||||
String, Other,
|
String, Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -83,6 +83,7 @@ extern crate serde_json;
|
|||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate reqwest;
|
extern crate reqwest;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
extern crate serde_qs;
|
||||||
extern crate serde_urlencoded;
|
extern crate serde_urlencoded;
|
||||||
extern crate tap_reader;
|
extern crate tap_reader;
|
||||||
extern crate try_from;
|
extern crate try_from;
|
||||||
@@ -389,7 +390,7 @@ impl<H: HttpSend> MastodonClient<H> for Mastodon<H> {
|
|||||||
let mut url = format!("{}/api/v1/accounts/{}/statuses", self.base, id);
|
let mut url = format!("{}/api/v1/accounts/{}/statuses", self.base, id);
|
||||||
|
|
||||||
if let Some(request) = request.into() {
|
if let Some(request) = request.into() {
|
||||||
url = format!("{}{}", url, request.to_querystring());
|
url = format!("{}{}", url, request.to_querystring()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = self.send(self.client.get(&url))?;
|
let response = self.send(self.client.get(&url))?;
|
||||||
|
|||||||
+118
-42
@@ -1,5 +1,23 @@
|
|||||||
|
use errors::Error;
|
||||||
|
use serde_qs;
|
||||||
use std::{borrow::Cow, convert::Into};
|
use std::{borrow::Cow, convert::Into};
|
||||||
|
|
||||||
|
mod bool_qs_serialize {
|
||||||
|
use serde::Serializer;
|
||||||
|
|
||||||
|
pub fn is_false(b: &bool) -> bool {
|
||||||
|
!*b
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize<S: Serializer>(b: &bool, s: S) -> Result<S::Ok, S::Error> {
|
||||||
|
if *b {
|
||||||
|
s.serialize_i64(1)
|
||||||
|
} else {
|
||||||
|
s.serialize_i64(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Builder for making a client.statuses() call
|
/// Builder for making a client.statuses() call
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@@ -9,16 +27,27 @@ use std::{borrow::Cow, convert::Into};
|
|||||||
/// # use elefren::StatusesRequest;
|
/// # use elefren::StatusesRequest;
|
||||||
/// let mut request = StatusesRequest::new();
|
/// let mut request = StatusesRequest::new();
|
||||||
/// request.only_media().pinned().since_id("foo");
|
/// request.only_media().pinned().since_id("foo");
|
||||||
/// # assert_eq!(&request.to_querystring()[..], "?only_media=1&pinned=1&since_id=foo");
|
/// # assert_eq!(&request.to_querystring().expect("Couldn't serialize qs")[..], "?only_media=1&pinned=1&since_id=foo");
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Clone, Debug, Default, PartialEq)]
|
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
|
||||||
pub struct StatusesRequest<'a> {
|
pub struct StatusesRequest<'a> {
|
||||||
|
#[serde(skip_serializing_if = "bool_qs_serialize::is_false")]
|
||||||
|
#[serde(serialize_with = "bool_qs_serialize::serialize")]
|
||||||
only_media: bool,
|
only_media: bool,
|
||||||
|
#[serde(skip_serializing_if = "bool_qs_serialize::is_false")]
|
||||||
|
#[serde(serialize_with = "bool_qs_serialize::serialize")]
|
||||||
exclude_replies: bool,
|
exclude_replies: bool,
|
||||||
|
#[serde(skip_serializing_if = "bool_qs_serialize::is_false")]
|
||||||
|
#[serde(serialize_with = "bool_qs_serialize::serialize")]
|
||||||
pinned: bool,
|
pinned: bool,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
max_id: Option<Cow<'a, str>>,
|
max_id: Option<Cow<'a, str>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
since_id: Option<Cow<'a, str>>,
|
since_id: Option<Cow<'a, str>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
limit: Option<usize>,
|
limit: Option<usize>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
min_id: Option<Cow<'a, str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Into<Option<StatusesRequest<'a>>> for &'a mut StatusesRequest<'a> {
|
impl<'a> Into<Option<StatusesRequest<'a>>> for &'a mut StatusesRequest<'a> {
|
||||||
@@ -30,6 +59,7 @@ impl<'a> Into<Option<StatusesRequest<'a>>> for &'a mut StatusesRequest<'a> {
|
|||||||
max_id: self.max_id.clone(),
|
max_id: self.max_id.clone(),
|
||||||
since_id: self.since_id.clone(),
|
since_id: self.since_id.clone(),
|
||||||
limit: self.limit.clone(),
|
limit: self.limit.clone(),
|
||||||
|
min_id: self.min_id.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,7 +86,7 @@ impl<'a> StatusesRequest<'a> {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use elefren::StatusesRequest;
|
/// # use elefren::StatusesRequest;
|
||||||
/// let mut request = StatusesRequest::new();
|
/// let mut request = StatusesRequest::new();
|
||||||
/// assert_eq!(&request.only_media().to_querystring(), "?only_media=1");
|
/// assert_eq!(&request.only_media().to_querystring().expect("Couldn't serialize qs"), "?only_media=1");
|
||||||
pub fn only_media(&mut self) -> &mut Self {
|
pub fn only_media(&mut self) -> &mut Self {
|
||||||
self.only_media = true;
|
self.only_media = true;
|
||||||
self
|
self
|
||||||
@@ -71,7 +101,10 @@ impl<'a> StatusesRequest<'a> {
|
|||||||
/// # use elefren::StatusesRequest;
|
/// # use elefren::StatusesRequest;
|
||||||
/// let mut request = StatusesRequest::new();
|
/// let mut request = StatusesRequest::new();
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// &request.exclude_replies().to_querystring(),
|
/// &request
|
||||||
|
/// .exclude_replies()
|
||||||
|
/// .to_querystring()
|
||||||
|
/// .expect("Couldn't serialize qs"),
|
||||||
/// "?exclude_replies=1"
|
/// "?exclude_replies=1"
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
@@ -88,7 +121,13 @@ impl<'a> StatusesRequest<'a> {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use elefren::StatusesRequest;
|
/// # use elefren::StatusesRequest;
|
||||||
/// let mut request = StatusesRequest::new();
|
/// let mut request = StatusesRequest::new();
|
||||||
/// assert_eq!(&request.pinned().to_querystring(), "?pinned=1");
|
/// assert_eq!(
|
||||||
|
/// &request
|
||||||
|
/// .pinned()
|
||||||
|
/// .to_querystring()
|
||||||
|
/// .expect("Couldn't serialize qs"),
|
||||||
|
/// "?pinned=1"
|
||||||
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
pub fn pinned(&mut self) -> &mut Self {
|
pub fn pinned(&mut self) -> &mut Self {
|
||||||
self.pinned = true;
|
self.pinned = true;
|
||||||
@@ -103,7 +142,13 @@ impl<'a> StatusesRequest<'a> {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use elefren::StatusesRequest;
|
/// # use elefren::StatusesRequest;
|
||||||
/// let mut request = StatusesRequest::new();
|
/// let mut request = StatusesRequest::new();
|
||||||
/// assert_eq!(&request.max_id("foo").to_querystring(), "?max_id=foo");
|
/// assert_eq!(
|
||||||
|
/// &request
|
||||||
|
/// .max_id("foo")
|
||||||
|
/// .to_querystring()
|
||||||
|
/// .expect("Couldn't serialize qs"),
|
||||||
|
/// "?max_id=foo"
|
||||||
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
pub fn max_id<S: Into<Cow<'a, str>>>(&mut self, max_id: S) -> &mut Self {
|
pub fn max_id<S: Into<Cow<'a, str>>>(&mut self, max_id: S) -> &mut Self {
|
||||||
self.max_id = Some(max_id.into());
|
self.max_id = Some(max_id.into());
|
||||||
@@ -118,7 +163,13 @@ impl<'a> StatusesRequest<'a> {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use elefren::StatusesRequest;
|
/// # use elefren::StatusesRequest;
|
||||||
/// let mut request = StatusesRequest::new();
|
/// let mut request = StatusesRequest::new();
|
||||||
/// assert_eq!(&request.since_id("foo").to_querystring(), "?since_id=foo");
|
/// assert_eq!(
|
||||||
|
/// &request
|
||||||
|
/// .since_id("foo")
|
||||||
|
/// .to_querystring()
|
||||||
|
/// .expect("Couldn't serialize qs"),
|
||||||
|
/// "?since_id=foo"
|
||||||
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
pub fn since_id<S: Into<Cow<'a, str>>>(&mut self, since_id: S) -> &mut Self {
|
pub fn since_id<S: Into<Cow<'a, str>>>(&mut self, since_id: S) -> &mut Self {
|
||||||
self.since_id = Some(since_id.into());
|
self.since_id = Some(since_id.into());
|
||||||
@@ -133,13 +184,40 @@ impl<'a> StatusesRequest<'a> {
|
|||||||
/// # extern crate elefren;
|
/// # extern crate elefren;
|
||||||
/// # use elefren::StatusesRequest;
|
/// # use elefren::StatusesRequest;
|
||||||
/// let mut request = StatusesRequest::new();
|
/// let mut request = StatusesRequest::new();
|
||||||
/// assert_eq!(&request.limit(10).to_querystring(), "?limit=10");
|
/// assert_eq!(
|
||||||
|
/// &request
|
||||||
|
/// .limit(10)
|
||||||
|
/// .to_querystring()
|
||||||
|
/// .expect("Couldn't serialize qs"),
|
||||||
|
/// "?limit=10"
|
||||||
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
pub fn limit(&mut self, limit: usize) -> &mut Self {
|
pub fn limit(&mut self, limit: usize) -> &mut Self {
|
||||||
self.limit = Some(limit);
|
self.limit = Some(limit);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the `?min_id=:min_id` flag for the .statuses() request
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # extern crate elefren;
|
||||||
|
/// # use elefren::StatusesRequest;
|
||||||
|
/// let mut request = StatusesRequest::new();
|
||||||
|
/// assert_eq!(
|
||||||
|
/// &request
|
||||||
|
/// .min_id("foobar")
|
||||||
|
/// .to_querystring()
|
||||||
|
/// .expect("Couldn't serialize qs"),
|
||||||
|
/// "?min_id=foobar"
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
pub fn min_id<S: Into<Cow<'a, str>>>(&mut self, min_id: S) -> &mut Self {
|
||||||
|
self.min_id = Some(min_id.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Turns this builder into a querystring
|
/// Turns this builder into a querystring
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@@ -149,42 +227,16 @@ impl<'a> StatusesRequest<'a> {
|
|||||||
/// # use elefren::StatusesRequest;
|
/// # use elefren::StatusesRequest;
|
||||||
/// let mut request = StatusesRequest::new();
|
/// let mut request = StatusesRequest::new();
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// &request.limit(10).pinned().to_querystring(),
|
/// &request
|
||||||
|
/// .limit(10)
|
||||||
|
/// .pinned()
|
||||||
|
/// .to_querystring()
|
||||||
|
/// .expect("Couldn't serialize qs"),
|
||||||
/// "?pinned=1&limit=10"
|
/// "?pinned=1&limit=10"
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
pub fn to_querystring(&self) -> String {
|
pub fn to_querystring(&self) -> Result<String, Error> {
|
||||||
let mut opts = vec![];
|
Ok(format!("?{}", serde_qs::to_string(&self)?))
|
||||||
|
|
||||||
if self.only_media {
|
|
||||||
opts.push("only_media=1".into());
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.exclude_replies {
|
|
||||||
opts.push("exclude_replies=1".into());
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.pinned {
|
|
||||||
opts.push("pinned=1".into());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref max_id) = self.max_id {
|
|
||||||
opts.push(format!("max_id={}", max_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref since_id) = self.since_id {
|
|
||||||
opts.push(format!("since_id={}", since_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(limit) = self.limit {
|
|
||||||
opts.push(format!("limit={}", limit));
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.is_empty() {
|
|
||||||
String::new()
|
|
||||||
} else {
|
|
||||||
format!("?{}", opts.join("&"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,6 +256,7 @@ mod tests {
|
|||||||
max_id: None,
|
max_id: None,
|
||||||
since_id: None,
|
since_id: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
min_id: None,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -221,6 +274,7 @@ mod tests {
|
|||||||
max_id: None,
|
max_id: None,
|
||||||
since_id: None,
|
since_id: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
min_id: None,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -238,6 +292,7 @@ mod tests {
|
|||||||
max_id: None,
|
max_id: None,
|
||||||
since_id: None,
|
since_id: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
min_id: None,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -254,6 +309,7 @@ mod tests {
|
|||||||
max_id: None,
|
max_id: None,
|
||||||
since_id: None,
|
since_id: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
min_id: None,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -270,6 +326,7 @@ mod tests {
|
|||||||
max_id: Some("foo".into()),
|
max_id: Some("foo".into()),
|
||||||
since_id: None,
|
since_id: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
min_id: None,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -286,6 +343,7 @@ mod tests {
|
|||||||
max_id: None,
|
max_id: None,
|
||||||
since_id: Some("foo".into()),
|
since_id: Some("foo".into()),
|
||||||
limit: None,
|
limit: None,
|
||||||
|
min_id: None,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -302,6 +360,24 @@ mod tests {
|
|||||||
max_id: None,
|
max_id: None,
|
||||||
since_id: None,
|
since_id: None,
|
||||||
limit: Some(42),
|
limit: Some(42),
|
||||||
|
min_id: None,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_min_id() {
|
||||||
|
let mut request = StatusesRequest::new();
|
||||||
|
request.min_id("foo");
|
||||||
|
assert_eq!(
|
||||||
|
request,
|
||||||
|
StatusesRequest {
|
||||||
|
only_media: false,
|
||||||
|
exclude_replies: false,
|
||||||
|
pinned: false,
|
||||||
|
max_id: None,
|
||||||
|
since_id: None,
|
||||||
|
limit: None,
|
||||||
|
min_id: Some("foo".into()),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -312,7 +388,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let mut $r = StatusesRequest::new();
|
let mut $r = StatusesRequest::new();
|
||||||
$b
|
$b
|
||||||
let qs = $r.to_querystring();
|
let qs = $r.to_querystring().expect("Failed to serialize querystring");
|
||||||
assert_eq!(&qs, $expected);
|
assert_eq!(&qs, $expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user