app_store_server_library/
utils.rs

1use base64::engine::general_purpose::STANDARD;
2use base64::{DecodeError, Engine};
3
4/// Converts a base64URL-encoded string to a standard base64-encoded string.
5///
6/// Replaces '/' with '+' and '_' with '-', and adds padding if needed.
7///
8/// # Examples
9///
10/// ```ignore
11/// let encoded_string = "aGVsbG8gd29ybGQh";
12/// let result = base64_url_to_base64(encoded_string);
13/// assert_eq!(result, "aGVsbG8gd29ybGQh==");
14/// ```
15pub(crate) fn base64_url_to_base64(encoded_string: &str) -> String {
16    let replaced_string = encoded_string
17        .replace('/', "+")
18        .replace('_', "-");
19
20    if replaced_string.len() % 4 != 0 {
21        return replaced_string.clone() + &"=".repeat(4 - replaced_string.len() % 4);
22    }
23
24    replaced_string
25}
26
27/// A trait for extending the functionality of Rust strings.
28pub trait StringExt {
29    /// Converts the string into a DER-encoded byte vector.
30    ///
31    /// This method attempts to parse the string as a DER-encoded byte sequence
32    /// and returns the result as a `Vec<u8>`. If the parsing fails, it returns
33    /// a `DecodeError`.
34    ///
35    /// # Errors
36    ///
37    /// If the string cannot be successfully parsed as DER-encoded bytes, this
38    /// method returns a `DecodeError` indicating the reason for the failure.
39    ///
40    fn as_der_bytes(&self) -> Result<Vec<u8>, DecodeError>;
41}
42
43impl StringExt for String {
44    fn as_der_bytes(&self) -> Result<Vec<u8>, DecodeError> {
45        STANDARD.decode(self)
46    }
47}
48
49impl StringExt for &str {
50    fn as_der_bytes(&self) -> Result<Vec<u8>, DecodeError> {
51        STANDARD.decode(self)
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_base64_url_to_base64() {
61        // Test with a base64URL-encoded string
62        let encoded_string = "aGVsbG8gd29ybGQh";
63        let result = base64_url_to_base64(encoded_string);
64        assert_eq!(result, "aGVsbG8gd29ybGQh");
65
66        // Test with a base64URL-encoded string requiring padding
67        let encoded_string_padding = "aGVsbG8gd29ybz";
68        let result_padding = base64_url_to_base64(encoded_string_padding);
69        assert_eq!(result_padding, "aGVsbG8gd29ybz==");
70    }
71}