use crate::{Error, HeaderValues, Headers, KnownHeaderName, Result};
use encoding_rs::Encoding;
use mime::Mime;
use std::str::FromStr;
pub fn encoding(headers: &Headers) -> &'static Encoding {
headers
.get_str(KnownHeaderName::ContentType)
.and_then(|c| Mime::from_str(c).ok())
.and_then(|m| {
m.params()
.find(|(name, _)| name.as_str() == "charset")
.and_then(|(_, v)| Encoding::for_label(v.as_str().as_bytes()))
})
.unwrap_or(encoding_rs::WINDOWS_1252)
}
pub fn validate_content_length(values: Option<&HeaderValues>) -> Result<Option<u64>> {
match values {
None => Ok(None),
Some(values) => parse_content_length(values)
.map(Some)
.ok_or_else(|| Error::InvalidHeaderValue(KnownHeaderName::ContentLength.into())),
}
}
pub(crate) fn parse_content_length(values: &HeaderValues) -> Option<u64> {
values
.as_str()
.filter(|cl| !cl.is_empty() && cl.bytes().all(|b| b.is_ascii_digit()))
.and_then(|cl| cl.parse::<u64>().ok())
}
pub(crate) fn is_tchar(b: u8) -> bool {
b.is_ascii_alphanumeric()
|| matches!(
b,
b'!' | b'#'
| b'$'
| b'%'
| b'&'
| b'\''
| b'*'
| b'+'
| b'-'
| b'.'
| b'^'
| b'_'
| b'`'
| b'|'
| b'~'
)
}