Struct ClientUnix

Source
pub struct ClientUnix { /* private fields */ }
Expand description

A simple HTTP (json) client using UNIX domain socket in Rust

Implementations§

Source§

impl ClientUnix

Source

pub async fn try_new(socket_path: &str) -> Result<Self, Error>

Create a new HTTP client and try to connect to it.

§Example
use http_client_unix_domain_socket::ClientUnix;

pub async fn new_client() {
    ClientUnix::try_new("/tmp/unix.socket").await.expect("ClientUnix::try_new");
}
Source

pub async fn try_reconnect(self) -> Result<Self, Error>

Reconnect to an existing ClientUnix.

Sometimes the server to which the client is connected may reboot, causing the client to disconnect. For simplicity, no automatic reconnection is implemented - it must be manually performed by calling this function. The error will be probably trigger during the ClientUnix::send_request(or ClientUnix::send_request_json) with this error Error::RequestSend.

§Example
use http_client_unix_domain_socket::{ClientUnix, Method, Error, ErrorAndResponse};

pub async fn reconnect_after_failure() {
    let mut client = ClientUnix::try_new("/tmp/unix.socket").await.expect("ClientUnix::try_new");
    let response_result = client.send_request("/nolanv", Method::GET, &[], None).await;

    if(matches!(
        response_result.err(),
        Some(ErrorAndResponse::InternalError(Error::RequestSend(e)))
            if e.is_canceled()
    )){
        client = client.try_reconnect().await.expect("client.try_reconnect");
    }
}
Source

pub async fn abort(self) -> Option<Error>

Abort the ClientUnix connection JoinHandle.

Used for stopping the connection JoinHandle, it’s also used for ClientUnix::try_reconnect. The returned Error can be used to know if it was stopped without any error.

Source

pub async fn send_request( &mut self, endpoint: &str, method: Method, headers: &[(&str, &str)], body_request: Option<Body>, ) -> Result<(StatusCode, Vec<u8>), ErrorAndResponse>

Send a raw HTTP request.

The ClientUnix::send_request method allows sending an HTTP request without serializing it. This method can be useful when communicating using a format other than JSON, or for endpoints that don’t return responses adhering to the JSON format. Error are wrapped in an Enum ErrorAndResponse that includes both ErrorAndResponse::InternalError and HTTP response ErrorAndResponse::ResponseUnsuccessful.

§Examples
§HTTP GET
use http_client_unix_domain_socket::{ClientUnix, Method, StatusCode, ErrorAndResponse};

pub async fn get_hello_world() {
    let mut client = ClientUnix::try_new("/tmp/unix.socket")
        .await
        .expect("ClientUnix::try_new");

    match client
        .send_request("/nolanv", Method::GET, &vec![("Host", "localhost")], None)
        .await
    {
        Err(ErrorAndResponse::ResponseUnsuccessful(status_code, response)) => {
            assert!(status_code == StatusCode::NOT_FOUND);
            assert!(response == "not found".as_bytes());
        }

        Ok((status_code, response)) => {
            assert_eq!(status_code, StatusCode::OK);
            assert_eq!(response, "Hello nolanv".as_bytes());
        }

        Err(_) => panic!("Something went wrong")
    }
}
§HTTP POST
use http_client_unix_domain_socket::{ClientUnix, Method, StatusCode, Body};

pub async fn post_hello_world() {
    let mut client = ClientUnix::try_new("/tmp/unix.socket")
        .await
        .expect("ClientUnix::try_new");

    let (status_code, response) = client
        .send_request("/", Method::POST, &[], Some(Body::from("nolanv")))
        .await
        .expect("client.send_request");

    assert_eq!(status_code, StatusCode::OK);
    assert_eq!(response, "Hello nolanv".as_bytes());
}
Source

pub async fn send_request_json<IN: Serialize, OUT: DeserializeOwned, ERR: DeserializeOwned>( &mut self, endpoint: &str, method: Method, headers: &[(&str, &str)], body_request: Option<&IN>, ) -> Result<(StatusCode, OUT), ErrorAndResponseJson<ERR>>

Send JSON HTTP request (feature = json)

Use ClientUnix::send_request, adding automatically the “Content-Type” header and handling JSON (de)serialization for both the request body and response. This method does not use the same Error Enum, enabling typed error responses instead via ErrorAndResponseJson.

§Examples
§HTTP POST JSON (feature = json)
use http_client_unix_domain_socket::{ClientUnix, Method, StatusCode, ErrorAndResponseJson};
use serde::{Deserialize, Serialize};

#[derive(Serialize)]
struct NameJson {
    name: String,
}

#[derive(Deserialize)]
struct HelloJson {
    hello: String,
}

#[derive(Deserialize, Debug)]
struct ErrorJson {
    msg: String,
}

pub async fn post_hello_world() {
    let mut client = ClientUnix::try_new("/tmp/unix.socket")
        .await
        .expect("ClientUnix::try_new");

    match client
        .send_request_json::<NameJson, HelloJson, ErrorJson>(
            "/nolanv",
            Method::POST,
            &vec![("Host", "localhost")],
            Some(&NameJson { name: "nolanv".into() }))
        .await
    {
        Err(ErrorAndResponseJson::ResponseUnsuccessful(status_code, response)) => {
            assert!(status_code == StatusCode::BAD_REQUEST);
            assert!(response.msg == "bad request");
        }

        Ok((status_code, response)) => {
            assert_eq!(status_code, StatusCode::OK);
            assert_eq!(response.hello, "nolanv");
        }

        Err(_) => panic!("Something went wrong")
    }
}

Trait Implementations§

Source§

impl Debug for ClientUnix

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.