1
Fork 0

Create crate

This commit is contained in:
Steffo 2024-11-09 11:01:26 +01:00
parent 1a374d3d98
commit c5e3fcfc99
Signed by: steffo
GPG key ID: 5ADA3868646C3FC0

View file

@ -1,14 +1,138 @@
pub fn add(left: u64, right: u64) -> u64 { use serde::Deserialize;
left + right
#[derive(Debug, Clone, Deserialize)]
pub struct Discovery {
pub links: Vec<DiscoveryDocument>,
} }
#[cfg(test)] #[derive(Debug, Clone, Deserialize)]
mod tests { pub struct DiscoveryDocument {
use super::*; pub rel: String,
pub href: String,
}
#[test] impl Discovery {
fn it_works() { pub async fn get(url: reqwest::Url) -> Result<Self, DiscoveryGetError> {
let result = add(2, 2); use DiscoveryGetError::*;
assert_eq!(result, 4);
log::debug!("Getting nodeinfo discovery at: {url}");
log::trace!("Sending GET request to: {url}");
let response = reqwest::get(url)
.await
.map_err(Request)?;
log::trace!("Checking headers of the response...");
response
.headers()
.get("Content-Type")
.ok_or(ContentTypeMissing)?
.eq("application/json")
.then_some(())
.ok_or(ContentTypeInvalid)?;
log::trace!("Attempting to parse nodeinfo discovery as JSON...");
let data = response.json::<Self>()
.await
.map_err(Parse)?;
Ok(data)
}
const WELLKNOWN_DISCOVERY_PATH: &str = "/.well-known/nodeinfo";
pub async fn discover(base: &reqwest::Url) -> Result<Self, DiscoveryDiscoverError> {
use DiscoveryDiscoverError::*;
log::debug!("Discovering nodeinfo at base: {base}");
let mut url = base.clone();
let path = Self::WELLKNOWN_DISCOVERY_PATH;
log::trace!("Setting URL path to `{path}`...");
url.set_path(path);
log::trace!("Unsetting URL query...");
url.set_query(None);
log::trace!("Unsetting URL fragment...");
url.set_fragment(None);
log::trace!("Setting URL scheme to HTTPS...");
url.set_scheme("https")
.map_err(UrlManipulation)?;
log::trace!("Attempting to retrieve nodeinfo via HTTPS...");
let https = Self::get(url.clone())
.await;
let https = match https {
Ok(data) => {
log::trace!("HTTPS retrieval was successful, returning...");
return Ok(data)
}
Err(err) => {
log::warn!("HTTPS retrieval failed.");
err
}
};
log::trace!("Setting URL scheme to HTTP...");
url.set_scheme("http")
.map_err(UrlManipulation)?;
log::trace!("Attempting to retrieve nodeinfo via HTTP...");
let http = Self::get(url.clone())
.await;
let http = match http {
Ok(data) => {
log::trace!("HTTP retrieval was successful, returning...");
return Ok(data)
}
Err(err) => {
log::warn!("HTTP retrieval failed.");
err
}
};
Err(
DiscoveryDiscoverError::Fetch(
DiscoveryDiscoverAttemptsErrors {
https,
http,
}
)
)
} }
} }
pub enum DiscoveryGetError {
/// The HTTP request failed.
Request(reqwest::Error),
/// The `Content-Type` header of the response is missing.
ContentTypeMissing,
/// The `Content-Type` header of the response is invalid.
ContentTypeInvalid,
/// The JSON document failed to be parsed.
Parse(reqwest::Error),
}
pub enum DiscoveryDiscoverError {
/// Manipulation of the URL scheme of the given base failed.
///
/// See [reqwest::Url::set_scheme] for possible causes.
UrlManipulation(()),
/// All attempts of fetching the discovery metadata failed.
Fetch(DiscoveryDiscoverAttemptsErrors),
}
pub struct DiscoveryDiscoverAttemptsErrors {
/// The error occurred during the HTTPS request.
pub https: DiscoveryGetError,
/// The error occurred during the HTTP request.
pub http: DiscoveryGetError,
}