use crate::error::*;
use crate::http::types::HeaderMap;
use reqwest::Url;
use reqwest::header;
use std::collections::HashMap;
pub fn get_links(headers: &HeaderMap) -> Result<HashMap<String, Vec<Url>>> {
let mut urls = HashMap::new();
if let Some(values) = headers.get(header::LINK.as_str()) {
for value in values {
let mut value = value.clone().try_into_string()?;
while !value.is_empty() {
if !value.starts_with('<') {
return Err(Error::InvalidArgument(format!(
"invalid link header value format: '{}'",
value
)));
}
let url_end = match value.find('>') {
None => {
return Err(Error::InvalidArgument(format!(
"invalid link header value format: '{}'",
value
)));
}
Some(idx) => idx,
};
let url: Url = (&value[1..url_end]).parse()?;
value.replace_range(0..url_end + 1, "");
if !value.starts_with("; rel=\"") {
return Err(Error::InvalidArgument(format!(
"invalid link header value format: '{}'",
value
)));
}
value.replace_range(0..7, "");
let rel_end = match value.find("\"") {
None => {
return Err(Error::InvalidArgument(format!(
"invalid link header value format: '{}'",
value
)));
}
Some(idx) => idx,
};
let rel = (&value[..rel_end]).to_owned();
value.replace_range(..rel_end + 1, "");
if value.starts_with(", ") {
value.replace_range(..2, "");
}
let entry = urls.entry(rel).or_insert_with(Vec::new);
(*entry).push(url);
}
}
}
Ok(urls)
}