atproto_oauth/
encoding.rs

1//! Base64 encoding utilities for OAuth operations.
2//!
3//! URL-safe base64 encoding/decoding for JWT headers and claims
4//! following RFC 7515 specifications.
5
6use anyhow::{Context, Result};
7use base64::{Engine as _, engine::general_purpose};
8use serde::{Deserialize, Serialize};
9use std::borrow::Cow;
10
11/// Trait for converting types to base64-encoded JSON.
12pub trait ToBase64 {
13    /// Convert the type to a base64-encoded JSON string.
14    fn to_base64(&self) -> Result<Cow<'_, str>>;
15}
16
17impl<T: Serialize> ToBase64 for T {
18    fn to_base64(&self) -> Result<Cow<'_, str>> {
19        let json_bytes = serde_json::to_vec(&self)?;
20        let encoded_json_bytes = general_purpose::URL_SAFE_NO_PAD.encode(json_bytes);
21        Ok(Cow::Owned(encoded_json_bytes))
22    }
23}
24
25/// Trait for converting from base64-encoded JSON to types.
26pub trait FromBase64: Sized {
27    /// Convert from a base64-encoded JSON string to the type.
28    fn from_base64<Input: ?Sized + AsRef<[u8]>>(raw: &Input) -> Result<Self>;
29}
30
31impl<T: for<'de> Deserialize<'de> + Sized> FromBase64 for T {
32    fn from_base64<Input: ?Sized + AsRef<[u8]>>(raw: &Input) -> Result<Self> {
33        let content = general_purpose::URL_SAFE_NO_PAD.decode(raw)?;
34        serde_json::from_slice(&content).context("unable to deserialize json")
35    }
36}