use http::HeaderValue;
pub(crate) fn is_json_media_type(value: &HeaderValue) -> bool {
read_essence(value).is_some_and(|essence| {
essence == "application/json"
|| essence
.split_once('/')
.and_then(|(_, subtype)| subtype.strip_suffix("+json"))
.is_some_and(|name| !name.is_empty())
})
}
fn read_essence(value: &HeaderValue) -> Option<String> {
let text = value.to_str().ok()?;
let essence = text
.split(';')
.next()
.unwrap_or_default()
.trim()
.to_ascii_lowercase();
let (kind, subtype) = essence.split_once('/')?;
(is_token(kind) && is_token(subtype)).then_some(essence)
}
fn is_token(text: &str) -> bool {
!text.is_empty()
&& text
.bytes()
.all(|byte| byte.is_ascii_alphanumeric() || b"!#$%&'*+-.^_`|~".contains(&byte))
}