1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
use alloc::{borrow::Cow, string::String, vec::Vec};
use core::str::from_utf8_unchecked;
/// Escape a Base64 string to a Base64-URL string. The conversion is not concerning with Base64 decoding. You need to make sure the input string is a correct Base64 string by yourself.
#[inline]
pub fn escape<S: ?Sized + AsRef<str>>(base64: &S) -> Cow<str> {
let base64 = base64.as_ref();
match escape_u8_slice(base64) {
Cow::Owned(base64_url) => {
let base64_url = unsafe { String::from_utf8_unchecked(base64_url) };
Cow::from(base64_url)
},
Cow::Borrowed(base64_url) => {
let base64_url = unsafe { from_utf8_unchecked(base64_url) };
Cow::from(base64_url)
},
}
}
/// Escape Base64 data to Base64-URL data. The conversion is not concerning with Base64 decoding. You need to make sure the input Base64 data is correct by yourself.
#[inline]
pub fn escape_u8_slice<S: ?Sized + AsRef<[u8]>>(base64: &S) -> Cow<[u8]> {
let base64 = base64.as_ref();
let length = base64.len();
let mut p = 0;
let first = loop {
if p == length {
return Cow::from(base64);
}
let e = base64[p];
match e {
43 => {
break 45;
},
47 => {
break 95;
},
61 => {
return Cow::from(&base64[..p]);
},
_ => (),
}
p += 1;
};
let mut base64_url = Vec::with_capacity(base64.len());
base64_url.extend_from_slice(&base64[..p]);
base64_url.push(first);
let mut start = p;
p += 1;
loop {
if p == length {
break;
}
let e = base64[p];
match e {
43 => {
base64_url.extend_from_slice(&base64[start..p]);
start = p + 1;
base64_url.push(45);
},
47 => {
base64_url.extend_from_slice(&base64[start..p]);
start = p + 1;
base64_url.push(95);
},
61 => break,
_ => (),
}
p += 1;
}
base64_url.extend_from_slice(&base64[start..p]);
Cow::from(base64_url)
}
/// In-place escape a Base64 string to a Base64-URL string. The conversion is not concerning with Base64 decoding. You need to make sure the input string is a correct Base64 string by yourself.
#[inline]
pub fn escape_in_place(base64: &mut String) -> &str {
let v = unsafe { base64.as_mut_vec() };
escape_vec_in_place(v);
base64.as_str()
}
/// In-place escape Base64 data to Base64-URL data. The conversion is not concerning with Base64 decoding. You need to make sure the input Base64 data is correct by yourself.
#[inline]
pub fn escape_vec_in_place(base64: &mut Vec<u8>) -> &[u8] {
let length = escape_u8_slice_in_place(base64.as_mut_slice()).len();
unsafe {
base64.set_len(length);
}
base64.as_slice()
}
/// In-place escape Base64 data to Base64-URL data. The conversion is not concerning with Base64 decoding. You need to make sure the input Base64 data is correct by yourself.
#[inline]
pub fn escape_u8_slice_in_place<S: ?Sized + AsMut<[u8]>>(base64: &mut S) -> &[u8] {
let base64 = base64.as_mut();
let mut len = base64.len();
for (index, n) in base64.iter_mut().enumerate() {
match *n {
43 => *n = 45,
47 => *n = 95,
61 => {
len = index;
break;
},
_ => (),
}
}
&base64[..len]
}
#[deprecated(since = "1.3.0", note = "Please use the `escape_in_place` function instead")]
/// Escape a Base64 string to a Base64-URL string. It is unsafe because the conversion is not concerning with Base64 decoding. You need to make sure the input string is a correct Base64 string by yourself.
#[inline]
pub fn unsafe_escape<S: Into<String>>(base64: S) -> String {
let mut base64 = base64.into();
escape_in_place(&mut base64);
base64
}
#[deprecated(since = "1.3.0", note = "Please use the `escape_in_place` function instead")]
/// In-place escape a Base64 string to a Base64-URL string. It is unsafe because the conversion is not concerning with Base64 decoding. You need to make sure the input string is a correct Base64 string by yourself.
#[inline]
pub fn unsafe_escape_string(base64: &mut String) {
escape_in_place(base64);
}
#[deprecated(since = "1.3.0", note = "Please use the `escape_vec_in_place` function instead")]
/// In-place escape Base64 data to Base64-URL data. It is unsafe because the conversion is not concerning with Base64 decoding. You need to make sure the input Base64 data is correct by yourself.
#[inline]
pub fn unsafe_escape_vec(base64: &mut Vec<u8>) {
escape_vec_in_place(base64);
}
#[deprecated(since = "1.3.0", note = "Please use the `escape_u8_slice_in_place` function instead")]
/// In-place escape Base64 data to Base64-URL data. It is unsafe because the conversion is not concerning with Base64 decoding. You need to make sure the input Base64 data is correct by yourself.
#[inline]
pub fn unsafe_escape_u8_slice<S: ?Sized + AsMut<[u8]>>(base64: &mut S) -> &[u8] {
escape_u8_slice_in_place(base64)
}