use crate::lib::alloc::{
string::{String, ToString},
vec::Vec,
};
use percent_encoding::{percent_encode, AsciiSet, CONTROLS};
const FRAGMENT: &AsciiSet = &CONTROLS.add(b' ').add(b'"').add(b'<').add(b'>').add(b'`');
const PATH: &AsciiSet = &FRAGMENT.add(b'#').add(b'?').add(b'{').add(b'}');
const USERINFO: &AsciiSet = &PATH
.add(b'/')
.add(b':')
.add(b';')
.add(b'=')
.add(b'@')
.add(b'[')
.add(b'\\')
.add(b']')
.add(b'^')
.add(b'|');
const PUBNUB_SET: &AsciiSet = &USERINFO.add(b'+').add(b'%').add(b'!').add(b'$');
const PUBNUB_NON_CHANNEL_PATH: &AsciiSet = &PUBNUB_SET.add(b',');
pub enum UrlEncodeExtension {
Default,
NonChannelPath,
}
pub fn url_encode(data: &[u8]) -> String {
url_encode_extended(data, UrlEncodeExtension::Default).to_string()
}
pub fn url_encode_extended(data: &[u8], extension: UrlEncodeExtension) -> String {
let set = match extension {
UrlEncodeExtension::Default => PUBNUB_SET,
UrlEncodeExtension::NonChannelPath => PUBNUB_NON_CHANNEL_PATH,
};
percent_encode(data, set).to_string()
}
pub fn join_url_encoded(strings: &[&str], sep: &str) -> Option<String> {
if strings.is_empty() {
return None;
}
Some(
strings
.iter()
.map(|val| url_encode(val.as_bytes()))
.collect::<Vec<String>>()
.join(sep),
)
}
#[cfg(any(feature = "subscribe", feature = "presence"))]
pub(crate) fn url_encoded_channels(channels: &[String]) -> String {
join_url_encoded(
channels
.iter()
.map(|v| v.as_str())
.collect::<Vec<&str>>()
.as_slice(),
",",
)
.unwrap_or(",".into())
}
#[cfg(any(feature = "subscribe", feature = "presence"))]
pub(crate) fn url_encoded_channel_groups(channel_groups: &[String]) -> Option<String> {
join_url_encoded(
channel_groups
.iter()
.map(|v| v.as_str())
.collect::<Vec<&str>>()
.as_slice(),
",",
)
.filter(|string| !string.is_empty())
}