1 use crate::http::{HttpEndpoint, HttpClient};
3 use std::convert::TryFrom;
4 use std::convert::TryInto;
6 /// A simple REST client for requesting resources using HTTP `GET`.
7 pub struct RestClient {
8 endpoint: HttpEndpoint,
13 /// Creates a new REST client connected to the given endpoint.
14 pub fn new(endpoint: HttpEndpoint) -> std::io::Result<Self> {
15 let client = HttpClient::connect(&endpoint)?;
16 Ok(Self { endpoint, client })
19 /// Requests a resource encoded in `F` format and interpreted as type `T`.
20 async fn request_resource<F, T>(&mut self, resource_path: &str) -> std::io::Result<T>
21 where F: TryFrom<Vec<u8>, Error = std::io::Error> + TryInto<T, Error = std::io::Error> {
22 let host = format!("{}:{}", self.endpoint.host(), self.endpoint.port());
23 let uri = format!("{}/{}", self.endpoint.path().trim_end_matches("/"), resource_path);
24 self.client.get::<F>(&uri, &host).await?.try_into()
31 use crate::http::BinaryResponse;
32 use crate::http::client_tests::{HttpServer, MessageBody};
34 /// Parses binary data as a string-encoded `u32`.
35 impl TryInto<u32> for BinaryResponse {
36 type Error = std::io::Error;
38 fn try_into(self) -> std::io::Result<u32> {
39 match std::str::from_utf8(&self.0) {
40 Err(e) => Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e)),
41 Ok(s) => match u32::from_str_radix(s, 10) {
42 Err(e) => Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e)),
50 async fn request_unknown_resource() {
51 let server = HttpServer::responding_with_not_found();
52 let mut client = RestClient::new(server.endpoint()).unwrap();
54 match client.request_resource::<BinaryResponse, u32>("/").await {
55 Err(e) => assert_eq!(e.kind(), std::io::ErrorKind::NotFound),
56 Ok(_) => panic!("Expected error"),
61 async fn request_malformed_resource() {
62 let server = HttpServer::responding_with_ok(MessageBody::Content("foo"));
63 let mut client = RestClient::new(server.endpoint()).unwrap();
65 match client.request_resource::<BinaryResponse, u32>("/").await {
66 Err(e) => assert_eq!(e.kind(), std::io::ErrorKind::InvalidData),
67 Ok(_) => panic!("Expected error"),
72 async fn request_valid_resource() {
73 let server = HttpServer::responding_with_ok(MessageBody::Content(42));
74 let mut client = RestClient::new(server.endpoint()).unwrap();
76 match client.request_resource::<BinaryResponse, u32>("/").await {
77 Err(e) => panic!("Unexpected error: {:?}", e),
78 Ok(n) => assert_eq!(n, 42),