// This example assumes the `serde` and `serde-json` features. // // If you are using the `rustc-serialize` feature, use `RustcDecodable` and `RustcEncodable` // instead of `Deserialize` and `Serialize`, respectively. #[macro_use] extern crate anterofit; #[macro_use] extern crate serde_derive; // The minimum imports needed to get this example working. // // You can glob-import if you like, but know that it will shadow `Result` // which may cause some confusing type-mismatch errors. use anterofit::{Adapter, Url}; #[derive(Debug, Deserialize)] struct Post { pub userid: Option, pub id: u64, pub title: String, pub body: String } /// Used to create a new Post. #[derive(Debug, Serialize)] struct NewPost<'a> { pub userid: u64, pub title: &'a str, pub body: &'a str, } service! { trait PostService { /// Get a Post by id. fn get_post(&self, id: u64) -> Post { GET("/posts/{}", id) } /// Get all posts. fn get_posts(&self) -> Vec { GET("/posts") } /// Get all posts by a specific user fn posts_by_user(&self, userid: u64) -> Vec { GET("/user/{}/posts", userid) } // TODO: demonstrate `query!{}` /// Create a new Post under the given user ID with the given title and body. fn new_post(&self, userid: u64, title: &str, body: &str) -> Post { POST("/posts/"); // We use the `EAGER:` keyword so we can use borrowed values in the body. // This serializes the body value immediately instead of waiting to serialize // it on the executor. body!(EAGER: NewPost { userid: userid, title: title, body: body }) } } } // So we can use `PostService` with `Adapter::arc_service`. unsizeable!(PostService); fn main() { // Navigate to this URL in your browser for details. Very useful test API. let url = Url::parse("https://jsonplaceholder.typicode.com").unwrap(); let adapter = Adapter::builder() .base_url(url) // When your REST API uses JSON in both requests and responses .serialize_json() .build(); // You can also get an `Arc` like this. let service = adapter.arc_service::(); create_post(&adapter); fetch_posts(&adapter); // have to deref-reref because coercion doesn't work as expected // see https://github.com/rust-lang/rust/issues/39801 user_posts(&*service); } /// Create a new Post. fn create_post(post_service: &P) { let post = post_service.new_post(42, "Hello", "World!") // If you don't want to block, the return value of exec() can be used as a Future // to poll for the result. However, it does shadow a couple methods of Future // so that you don't have to import the trait to use them. // See the docs of Call for more info. .exec().block() .unwrap(); println!("Created post: {:?}", post); } /// Fetch the top 3 posts in the database. // Service traits can be object-safe fn fetch_posts(post_service: &PostService) { let posts = post_service.get_posts() // Shorthand for .exec().wait(), but executes the request on the current thread. .exec_here() .unwrap(); for post in posts.into_iter().take(3) { println!("Fetched post: {:?}", post); } } fn user_posts(post_service: &PostService) { post_service.posts_by_user(1) // This will be executed asynchronously when the request is completed .on_complete(|posts| for post in posts { println!("User post: {:?}", post); }) .exec().ignore(); }