//! Minimal percent-encoding/decoding for the bridge shared secret. const UNRESERVED: &[u8] = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"; /// Percent-encode everything outside the unreserved set. pub fn percent_encode(input: &str) -> String { let mut out = String::with_capacity(input.len()); for byte in input.bytes() { if UNRESERVED.contains(&byte) { out.push(byte as char); } else { out.push_str(&format!("%{byte:02X}")); } } out } /// Decode `%XX` escapes. `+` is left alone (never produced by `percent_encode`). pub fn percent_decode(input: &str) -> String { let bytes = input.as_bytes(); let mut out = Vec::with_capacity(bytes.len()); let mut i = 0; while i < bytes.len() { if bytes[i] == b'%' && i + 2 < bytes.len() { let hex = &input[i + 1..i + 3]; if let Ok(byte) = u8::from_str_radix(hex, 16) { out.push(byte); i += 3; continue; } } out.push(bytes[i]); i += 1; } String::from_utf8_lossy(&out).into_owned() }