Create crate
This commit is contained in:
parent
1a374d3d98
commit
c5e3fcfc99
1 changed files with 135 additions and 11 deletions
|
@ -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]
|
}
|
||||||
fn it_works() {
|
|
||||||
let result = add(2, 2);
|
impl Discovery {
|
||||||
assert_eq!(result, 4);
|
pub async fn get(url: reqwest::Url) -> Result<Self, DiscoveryGetError> {
|
||||||
}
|
use DiscoveryGetError::*;
|
||||||
|
|
||||||
|
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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue