identity_jose/jwu/
base64.rs

1// Copyright 2020-2023 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use identity_core::convert::Base;
5use identity_core::convert::BaseEncoding;
6use serde::de::DeserializeOwned;
7use serde::Serialize;
8
9use crate::error::Error;
10use crate::error::Result;
11
12/// Encode the given slice in url-safe base64 with no padding.
13pub fn encode_b64(data: impl AsRef<[u8]>) -> String {
14  BaseEncoding::encode(data.as_ref(), Base::Base64Url)
15}
16
17/// Decode the given url-safe, unpadded base64-encoded slice into its raw bytes.
18pub fn decode_b64(data: impl AsRef<[u8]>) -> Result<Vec<u8>> {
19  std::str::from_utf8(data.as_ref())
20    .map_err(Error::InvalidUtf8)
21    .and_then(|string| BaseEncoding::decode(string, Base::Base64Url).map_err(Error::InvalidBase64))
22}
23
24/// Serialize the given data into JSON and encode the result in url-safe base64.
25pub fn encode_b64_json<T>(data: &T) -> Result<String>
26where
27  T: Serialize,
28{
29  serde_json::to_vec(data).map(encode_b64).map_err(Error::InvalidJson)
30}
31
32/// Decode the given url-safe base64-encoded slice into its raw bytes and try to deserialize it into `T`.
33pub fn decode_b64_json<T>(data: impl AsRef<[u8]>) -> Result<T>
34where
35  T: DeserializeOwned,
36{
37  decode_b64(data).and_then(|data| serde_json::from_slice(&data).map_err(Error::InvalidJson))
38}
39
40#[cfg(test)]
41mod tests {
42  use super::*;
43
44  #[test]
45  fn smoke() {
46    assert!(decode_b64(encode_b64(b"libjose")).is_ok());
47  }
48}