flawless-http 1.0.0-beta.3

HTTP client for https://flawless.dev.
Documentation
use base64::{prelude::BASE64_STANDARD, Engine};
use flawless_wasabi::{submit, Input};

use crate::{Config, Error, Response};

use super::HTTPTransport;

/// This is a marker type, indicating that all performed operations are idempotent.
///
/// It uses the flawless wasabi (WebAssembly ABI) to perform the HTTP requests.
pub struct Idempotent;

/// A transport layer that uses the flawless wasabi (WebAssembly ABI).
pub struct Flawless;

type Headers = Vec<(String, String)>;
type Ret = Result<Response, Error>;

impl HTTPTransport for Flawless {
    fn send(self, config: Config, method: String, url: String, headers: Headers, body: Vec<u8>) -> Ret {
        send(config, method, url, headers, body)
    }
}

impl HTTPTransport for Idempotent {
    fn send(self, config: Config, method: String, url: String, headers: Headers, body: Vec<u8>) -> Ret {
        send(config, method, url, headers, body)
    }
}

/// Perform an HTTP request.
///
/// There is no difference, between the idempotent and non-idempotent call. However, the `Config` parameter
/// of the idempotent marker type should always have the `idempotent` boolean set to `true`.
fn send(config: Config, method: String, url: String, headers: Headers, body: Vec<u8>) -> Ret {
    let body = BASE64_STANDARD.encode(body);
    let req = flawless_wasabi::HttpRequest { config: config.into(), method, url, headers, body };
    match submit(&Input::HTTPRequest(req)).expect("http_request(req) call shouldn't fail") {
        flawless_wasabi::Output::HTTPResponse(res) => res.map(|r| r.into()).map_err(|e| e.into()),
        _ => unreachable!("http_request(req) returns other type"),
    }
}