use std::str::FromStr;
use ::http::{
uri::{InvalidUri, PathAndQuery, Scheme},
Uri,
};
use percent_encoding::{utf8_percent_encode, AsciiSet};
use crate::{Request, Response};
const WELL_KNOWN_PATH: &str = "/.well-known/webfinger";
#[allow(unused)]
const JRD_CONTENT_TYPE: &str = "application/jrd+json";
const QUERY: AsciiSet = percent_encoding::CONTROLS
.add(b' ')
.add(b'"')
.add(b'#')
.add(b'<')
.add(b'>')
.add(b'[')
.add(b'\\')
.add(b']')
.add(b'^')
.add(b'`')
.add(b'{')
.add(b'|')
.add(b'}')
.add(b'=')
.add(b'&');
impl TryFrom<&Request> for PathAndQuery {
type Error = InvalidUri;
fn try_from(query: &Request) -> Result<PathAndQuery, InvalidUri> {
let resource = query.resource.to_string();
let resource = utf8_percent_encode(&resource, &QUERY).to_string();
let mut path = WELL_KNOWN_PATH.to_owned();
path.push_str("?resource=");
path.push_str(&resource);
for rel in &query.link_relation_types {
let rel = utf8_percent_encode(rel, &QUERY).to_string();
path.push_str("&rel=");
path.push_str(&rel);
}
PathAndQuery::from_str(&path)
}
}
impl TryFrom<&Request> for Uri {
type Error = http::Error;
fn try_from(query: &Request) -> Result<Uri, http::Error> {
let path_and_query = PathAndQuery::try_from(query)?;
const SCHEME: Scheme = Scheme::HTTPS;
Uri::builder()
.scheme(SCHEME)
.authority(query.host.clone())
.path_and_query(path_and_query)
.build()
}
}
impl TryFrom<&Response> for http::Response<()> {
type Error = http::Error;
fn try_from(_: &Response) -> Result<http::Response<()>, http::Error> {
http::Response::builder()
.header("Content-Type", "application/jrd+json")
.body(())
}
}