1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
//! Wrap REST calls with Rust traits.
//!
//! ```rust
//! #[macro_use] extern crate anterofit;
//! # fn main() {}
//!
//! service! {
//!     /// Trait wrapping `myservice.com` API.
//!     pub trait MyService {
//!         /// Get the version of this API.
//!         fn api_version(&self) -> String {
//!             GET("/version")
//!         }
//!
//!         /// Register a user with the API.
//!         fn register(&self, username: &str, password: &str) {
//!             POST("/register");
//!             fields! {
//!                 username, password
//!             }
//!         }
//!     }
//! }
//! ```
//!
//! # Important Types
//!
//! ## Service Traits
//! Created with the `service!{}` macro as shown above, service traits encompass the actual request
//! submission and response parsing. Each service trait is automatically implemented for
//! `Adapter`, and is object-safe by default, so you can use generic bounds or trait object coercion
//! to narrow the scope:
//!
//! ```rust,ignore
//! fn print_api_version(service: &MyService) {
//!     // This completes synchronously, blocking until the request is complete.
//!     let api_version = service.api_version().exec_here().unwrap();
//!     println!("API version: {}", api_version);
//! }
//!
//! fn register_user<S: MyService>(service: &S, username: &str, password: &str) {
//!     // By default, this will complete asynchronously.
//!     service.register(username, password)
//!         // exec() queues the request on the executor,
//!         // and ignore() silences the `unused_result` lint for `Call`.
//!         .exec().ignore();
//!
//!     // This function returns immediately; all the work is done on the executor.
//! }
//! ```
//!
//! For more details, see the [`service!{}` macro](macro.service.html).
//!
//! ## Adapter
//! Built via `Adapter::builder()`, this is the starting point for all requests. It encompasses
//! five core components, and one very important property:
//!
//! * The `Executor` is responsible for taking prepared requests and executing them. Since Anterofit
//! is primarily designed to be asynchronous, the executor should submit jobs to be completed in the
//! background. Several executors are provided in the `executor` module, but a sane default
//! for low-volume asynchronous requests is provided automatically.
//!
//! * The `Interceptor` is a non-essential but endlessly useful component which can modify
//! request parameters before they are submitted. This currently encompasses modifying the request
//! URL and adding or overwriting HTTP headers. If your app requires some sort of API key or
//! authentication header, you can add an interceptor to your adapter to automatically include
//! the appropriate credentials with each request:
//!
//! ```rust,no_run
//! use anterofit::{Adapter, Url};
//! use anterofit::net::intercept::AddHeader;
//! use anterofit::net::header::{Headers, Authorization, Bearer};
//!
//! let adapter = Adapter::builder()
//!     .base_url(Url::parse("https://myservice.com/api").unwrap())
//!     .interceptor(AddHeader(Authorization (
//!         Bearer {
//!             token: "asdf1234hjkl5678".to_string()
//!         }
//!     )))
//!     .build();
//! ```
//!
//! `Interceptor` is also implemented for closures of the kind `Fn(&mut anterofit::net::request::RequestHead)`,
//! but common operations are implemented as types in the `anterofit::net::interceptor` module.
//! You can also chain interceptors together, or call `box_interceptor()` to transform
//! it to `Box<Interceptor>` if you need to name the full type of `Adapter`.
//!
//! * The `Serializer` is responsible for taking a strongly typed request body and converting
//! it to something that can be read into the HTTP stream, such as JSON or a raw byte sequence.
//!
//! * Conversely, the `Deserializer` is responsible for taking a response body in some predetermined
//! format, such as JSON or XML, and reading out a strongly typed value.
//!
//! If you just want JSON serialization and deserialization and don't care about the details,
//! use the `serialize_json()` method of your adapter builder to set the serializer and deserializer
//! simultaneously.
//!
//! * The `Client` (`hyper::client::Client`) is responsible for managing proxies, DNS resolution,
//! and bootstrapping connections. A default instance will be constructed automatically if one is
//! not provided, but you can configure your own instance to tweak some low-level stuff like
//! timeouts or to use a particular proxy.
//!
//! * Finally, the `base_url`, if provided, is automatically prepended to every request URL. This would
//! generally be the protocol, domain and perhaps a path prefix, while request URLs can be standalone paths.
//! That way you can easily swap between, for example, testing and production endpoints implementing
//! the same REST API:
//!
//! ```rust
//! # extern crate anterofit;
//! # fn print_api_version<T>(_: &T) {}
//! # fn register_user<T>(_: &T, _: &str, _: &str) {}
//! # fn main() {
//! use anterofit::{Adapter, Url};
//!
//! let adapter = Adapter::builder()
//!     .base_url(Url::parse("https://test.myservice.com/api").unwrap())
//!     .build();
//!
//! print_api_version(&adapter);
//! register_user(&adapter, "username", "password");
//!
//! let adapter = Adapter::builder()
//!     .base_url(Url::parse("https://prod.myservice.com/api").unwrap())
//!     .build();
//!
//! print_api_version(&adapter);
//! register_user(&adapter, "username", "password");
//! # }
//! ```
//!
//! ## `Request`
//! This type wraps the return value of every service trait method. Unlike in Retrofit
//! (v1; v2 uses this pattern now, but is more verbose), where the request is determined to
//! be synchronous or asynchronous at the service method declaration site, `Request` gives the power
//! over this choice to the caller so that no change to the trait is needed to change the execution
//! context:
//!
//! ```rust,ignore
//! fn print_api_version(service: &MyService) {
//!     service.api_version()
//!         // This closure will be called with the `String` value on the executor
//!         .on_complete(|api_version| println!("API version: {}", api_version))
//!         // We don't care about the result since it's `()` anyway.
//!         .exec().ignore();
//! }
//! ```
//!
//! ## `Call`
//! Returned by `Request::exec()`, this type is a pollable `Future` which will yield the result
//! of the request when it is ready. If there was an error in constructing the request,
//! the result will be available immediately. `Call` shadows `Future::poll()` and `Future::wait()`
//! with inherent methods that do not require the use of types from the `futures` crate, so you
//! have a choice over whether you want to use futures in your app or not.
#![warn(missing_docs)]
#![cfg_attr(feature = "nightly", feature(insert_str))]
#![recursion_limit="100"]

#[macro_use]
extern crate quick_error;

extern crate futures;

#[macro_use]
extern crate mime as mime_;

extern crate multipart;

#[cfg(feature = "rustc-serialize")]
extern crate rustc_serialize;

extern crate url;

pub extern crate hyper;

#[macro_use]
mod macros;

pub mod mime;

pub mod net;

pub mod serialize;

pub mod executor;

pub mod error;

pub use error::Error;

pub use hyper::Url;

pub use net::{Adapter, AbsAdapter};

pub use net::body::RawBody;

pub use net::request::Request;

/// The result type for this crate; used frequently in public APIs.
///
/// Recommended to be used as `anterofit::Result` to avoid confusing
/// shadowing of `std::result::Result`.
pub type Result<T> = ::std::result::Result<T, Error>;

/// Strong typing hint for delegate adapter-getters.
#[doc(hidden)]
pub fn get_adapter<D, A: AbsAdapter, F: FnOnce(&D) -> &A>(delegate: &D, map: F) -> &A {
    map(delegate)
}