use http::HeaderMap;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ChDeprecation {
pub raw: String,
pub expiry_date: Option<String>,
pub rel: Option<String>,
}
pub(crate) fn parse_ch_expiry(headers: &HeaderMap) -> Option<ChDeprecation> {
let raw = headers
.get("CH-Expiry-Date")?
.to_str()
.ok()?
.to_string();
let (expiry_date, rel) = parse_ch_expiry_parts(&raw);
Some(ChDeprecation {
raw,
expiry_date,
rel,
})
}
fn parse_ch_expiry_parts(raw: &str) -> (Option<String>, Option<String>) {
let rel_key = "; rel=";
if let Some(pos) = raw.find(rel_key) {
let date_part = raw[..pos].trim();
let exp: Option<String> = if date_part.is_empty() {
None
} else {
Some(date_part.to_string())
};
let r = raw[pos + rel_key.len()..].trim();
let rel = if r.is_empty() {
None
} else {
Some(r.to_string())
};
return (exp, rel);
}
let mut expiry_date: Option<String> = None;
let mut rel: Option<String> = None;
for part in raw.split(';').map(str::trim) {
if let Some(r) = part.strip_prefix("rel=") {
rel = Some(r.trim().to_string());
} else if !part.is_empty() && !part.contains('=') && expiry_date.is_none() {
expiry_date = Some(part.to_string());
}
}
(expiry_date, rel)
}
#[cfg(test)]
mod tests {
use super::*;
use http::HeaderValue;
#[test]
fn parses_ch_expiry_header_with_rel_and_trailing_version() {
let mut h = HeaderMap::new();
h.insert(
"CH-Expiry-Date",
HeaderValue::from_static(
"2016-01-01; rel=application/vnd.companieshouse.company-profile+json; version=1",
),
);
let d = parse_ch_expiry(&h).expect("parsed");
assert_eq!(d.expiry_date.as_deref(), Some("2016-01-01"));
assert_eq!(
d.rel.as_deref(),
Some("application/vnd.companieshouse.company-profile+json; version=1")
);
}
}