http-signature-normalization-reqwest 0.14.1

An HTTP Signatures library that leaves the signing to you
Documentation
use base64::{engine::general_purpose::STANDARD, Engine};
use http_signature_normalization_reqwest::{digest::ring::Sha256, prelude::*};
use reqwest::{
    header::{ACCEPT, USER_AGENT},
    Client,
};

async fn request(config: Config) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let digest = Sha256::new();

    let client = Client::new();

    let request = client
        .post("http://127.0.0.1:8010/")
        .header(USER_AGENT, "Reqwest")
        .header(ACCEPT, "text/plain")
        .signature_with_digest(config, "my-key-id", digest, "Hewwo-owo", |s| {
            println!("Signing String\n{}", s);
            Ok(STANDARD.encode(s)) as Result<_, MyError>
        })
        .await?;

    let body = client
        .execute(request)
        .await
        .map_err(MyError::SendRequest)?
        .bytes()
        .await
        .map_err(MyError::Body)?;

    println!("{:?}", body);
    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    std::env::set_var("RUST_LOG", "info");
    pretty_env_logger::init();

    tokio::spawn(async move {
        let config = Config::default().require_header("accept");

        request(config.clone()).await?;
        request(config.mastodon_compat()).await
    })
    .await?
}

#[derive(Debug)]
pub enum MyError {
    Convert(SignError),

    SendRequest(reqwest::Error),

    Body(reqwest::Error),
}

impl std::fmt::Display for MyError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Convert(_) => f.write_str("Failed to create signing string"),
            Self::SendRequest(_) => f.write_str("Failed to send request"),
            Self::Body(_) => f.write_str("Failed to retrieve response body"),
        }
    }
}

impl std::error::Error for MyError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            Self::Convert(c) => Some(c),
            Self::SendRequest(s) => Some(s),
            Self::Body(b) => Some(b),
        }
    }
}

impl From<SignError> for MyError {
    fn from(value: SignError) -> Self {
        Self::Convert(value)
    }
}

impl From<reqwest::Error> for MyError {
    fn from(value: reqwest::Error) -> Self {
        Self::SendRequest(value)
    }
}