base64-const 0.0.6

Base64 encode/decode with const-friendly decode and URL-safe macros
Documentation
use std::str::Chars;

pub fn to_url_safe(input:impl AsRef<str>) -> String {
    ToUrlSafeIter::new(input.as_ref().chars()).collect()
}

pub fn from_url_safe(input:impl AsRef<str>) -> String {
    FromUrlSafeIter::new(input.as_ref().chars()).collect()
}


pub struct ToUrlSafeIter<'a> {
    pub chars: Chars<'a>,
}

impl<'a> ToUrlSafeIter<'a> {
    pub fn new(chars:Chars<'a>) -> Self{
        return ToUrlSafeIter {
            chars,
        };
    }
}

impl<'a> Iterator for ToUrlSafeIter<'a> {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        match self.chars.next(){
            None => None,
            Some(ch) if ch == '+' => Some('-'),
            Some(ch) if ch == '/' => Some('_'),
            Some(ch) if ch == '=' => None,
            ch => ch,
        }
    }
}

pub struct FromUrlSafeIter<'a> {
    pub chars: Chars<'a>,
    count:usize
}

impl<'a> FromUrlSafeIter<'a> {
    pub fn new(chars:Chars<'a>) -> Self{
        return FromUrlSafeIter {
            chars,
            count:0
        };
    }
}

impl<'a> Iterator for FromUrlSafeIter<'a> {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        let result= match self.chars.next(){
            None if self.count % 4 > 0 => Some('='),
            None => return None,
            Some(ch) if ch == '-' => Some('+'),
            Some(ch) if ch == '_' => Some('/'),
            ch => ch,
        };
        self.count += 1;
        result
    }
}

#[cfg(test)]
mod tests {
    use crate::{base64_url_safe, base64_url_unsafe};

    use super::*;

    #[test]
    fn test_to_url_safe() {
        assert_eq!(to_url_safe(r###"1234++/+//abc==="###), r###"1234--_-__abc"###)
    }

    #[test]
    fn test_from_url_safe() {
        assert_eq!(from_url_safe(r###"1234--_-__abc"###), r###"1234++/+//abc==="###)
    }

    #[test]
    fn test_base64_url_unsafe_macro() {
        let message = base64_url_unsafe!(r###"1234--_-__abc"###);
        assert_eq!(message, r###"1234++/+//abc==="###);
    }

    #[test]
    fn test_base64_url_safe_macro() {
        let message = base64_url_safe!(r###"1234++/+//abc==="###);
        assert_eq!(message, r###"1234--_-__abc"###);
    }
}