@ -58,7 +58,7 @@ use std::ops;
use json ::Error as SerdeError ;
use json ::Error as SerdeError ;
use reqwest ::Error as HttpError ;
use reqwest ::Error as HttpError ;
use reqwest ::{ Client , StatusCode } ;
use reqwest ::{ Client , Response , StatusCode } ;
use reqwest ::header ::{ Authorization , Bearer , Headers } ;
use reqwest ::header ::{ Authorization , Bearer , Headers } ;
use entities ::prelude ::* ;
use entities ::prelude ::* ;
@ -74,20 +74,11 @@ macro_rules! methods {
fn $method < T : for < ' de > serde ::Deserialize < ' de > > ( & self , url : String )
fn $method < T : for < ' de > serde ::Deserialize < ' de > > ( & self , url : String )
-> Result < T >
-> Result < T >
{
{
use std ::io ::Read ;
let response = self . client . $method ( & url )
let mut response = self . client . $method ( & url )
. headers ( self . headers . clone ( ) )
. headers ( self . headers . clone ( ) )
. send ( ) ? ;
. send ( ) ? ;
let mut vec = Vec ::new ( ) ;
json_convert_response ( response )
response . read_to_end ( & mut vec ) ? ;
if let Ok ( t ) = json ::from_slice ( & vec ) {
Ok ( t )
} else {
Err ( Error ::Api ( json ::from_slice ( & vec ) ? ) )
}
}
}
) +
) +
} ;
} ;
@ -103,7 +94,6 @@ macro_rules! route {
#[ doc = " # Errors " ]
#[ doc = " # Errors " ]
/// If `access_token` is not set.
/// If `access_token` is not set.
pub fn $name ( & self , $( $param : $typ , ) * ) -> Result < $ret > {
pub fn $name ( & self , $( $param : $typ , ) * ) -> Result < $ret > {
use std ::io ::Read ;
use reqwest ::multipart ::Form ;
use reqwest ::multipart ::Form ;
let form_data = Form ::new ( )
let form_data = Form ::new ( )
@ -111,7 +101,7 @@ macro_rules! route {
. file ( stringify! ( $param ) , $param . as_ref ( ) ) ?
. file ( stringify! ( $param ) , $param . as_ref ( ) ) ?
) * ;
) * ;
let mut response = self . client . post ( & self . route ( concat! ( "/api/v1/" , $url ) ) )
let response = self . client . post ( & self . route ( concat! ( "/api/v1/" , $url ) ) )
. headers ( self . headers . clone ( ) )
. headers ( self . headers . clone ( ) )
. multipart ( form_data )
. multipart ( form_data )
. send ( ) ? ;
. send ( ) ? ;
@ -124,15 +114,7 @@ macro_rules! route {
return Err ( Error ::Server ( status ) ) ;
return Err ( Error ::Server ( status ) ) ;
}
}
let mut vec = Vec ::new ( ) ;
json_convert_response ( response )
response . read_to_end ( & mut vec ) ? ;
match json ::from_slice ::< $ret > ( & vec ) {
Ok ( res ) = > Ok ( res ) ,
Err ( _ ) = > Err ( Error ::Api ( json ::from_slice ( & vec ) ? ) ) ,
}
}
}
route ! { $( $rest ) * }
route ! { $( $rest ) * }
@ -146,7 +128,6 @@ macro_rules! route {
#[ doc = " # Errors " ]
#[ doc = " # Errors " ]
/// If `access_token` is not set.
/// If `access_token` is not set.
pub fn $name ( & self , $( $param : $typ , ) * ) -> Result < $ret > {
pub fn $name ( & self , $( $param : $typ , ) * ) -> Result < $ret > {
use std ::io ::Read ;
let form_data = json ! ( {
let form_data = json ! ( {
$(
$(
@ -154,7 +135,7 @@ macro_rules! route {
) *
) *
} ) ;
} ) ;
let mut response = self . client . post ( & self . route ( concat! ( "/api/v1/" , $url ) ) )
let response = self . client . post ( & self . route ( concat! ( "/api/v1/" , $url ) ) )
. headers ( self . headers . clone ( ) )
. headers ( self . headers . clone ( ) )
. json ( & form_data )
. json ( & form_data )
. send ( ) ? ;
. send ( ) ? ;
@ -167,14 +148,7 @@ macro_rules! route {
return Err ( Error ::Server ( status ) ) ;
return Err ( Error ::Server ( status ) ) ;
}
}
let mut vec = Vec ::new ( ) ;
json_convert_response ( response )
response . read_to_end ( & mut vec ) ? ;
match json ::from_slice ( & vec ) {
Ok ( res ) = > Ok ( res ) ,
Err ( _ ) = > Err ( Error ::Api ( json ::from_slice ( & vec ) ? ) ) ,
}
}
}
route ! { $( $rest ) * }
route ! { $( $rest ) * }
@ -392,21 +366,13 @@ impl Mastodon {
/// Post a new status to the account.
/// Post a new status to the account.
pub fn new_status ( & self , status : StatusBuilder ) -> Result < Status > {
pub fn new_status ( & self , status : StatusBuilder ) -> Result < Status > {
use std ::io ::Read ;
let mut response = self . client . post ( & self . route ( "/api/v1/statuses" ) )
let response = self . client . post ( & self . route ( "/api/v1/statuses" ) )
. headers ( self . headers . clone ( ) )
. headers ( self . headers . clone ( ) )
. json ( & status )
. json ( & status )
. send ( ) ? ;
. send ( ) ? ;
let mut vec = Vec ::new ( ) ;
json_convert_response ( response )
response . read_to_end ( & mut vec ) ? ;
if let Ok ( t ) = json ::from_slice ( & vec ) {
Ok ( t )
} else {
Err ( Error ::Api ( json ::from_slice ( & vec ) ? ) )
}
}
}
/// Get the federated timeline for the instance.
/// Get the federated timeline for the instance.
@ -526,3 +492,24 @@ from! {
HttpError , Http ,
HttpError , Http ,
IoError , Io ,
IoError , Io ,
}
}
// Convert the HTTP response body from JSON. Pass up deserialization errors
// transparently.
fn json_convert_response < T : for < ' de > serde ::Deserialize < ' de > > ( mut response : Response ) -> Result < T > {
use std ::io ::Read ;
let mut vec = Vec ::new ( ) ;
response . read_to_end ( & mut vec ) ? ;
match json ::from_slice ( & vec ) {
Ok ( t ) = > Ok ( t ) ,
// If deserializing into the desired type fails try again to
// see if this is an error response.
Err ( e ) = > {
if let Ok ( error ) = json ::from_slice ( & vec ) {
return Err ( Error ::Api ( error ) ) ;
}
Err ( e . into ( ) )
} ,
}
}