Rename acrate-hostmeta
to acrate_rd
This commit is contained in:
parent
7d1e1d2dd7
commit
8aa0d31041
12 changed files with 185 additions and 43 deletions
|
@ -3,13 +3,13 @@
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
<exclude-output />
|
<exclude-output />
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<sourceFolder url="file://$MODULE_DIR$/acrate-hostmeta/src" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/acrate-hostmeta/tests" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/acrate-inbox/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/acrate-inbox/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/acrate-nodeinfo/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/acrate-nodeinfo/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/acrate-nodeinfo/tests" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/acrate-nodeinfo/tests" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/acrate-webfinger/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/acrate-webfinger/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/acrate_database/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/acrate_database/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/acrate_rd/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/acrate_rd/tests" isTestSource="true" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = ["acrate_database", "acrate-hostmeta", "acrate-nodeinfo", "acrate-webfinger"]
|
members = ["acrate_database", "acrate_rd", "acrate-nodeinfo", "acrate-webfinger"]
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
/// Extract the MIME type from the value of the `Content-Type` header.
|
|
||||||
pub fn extract_mime_from_content_type(value: &reqwest::header::HeaderValue) -> Option<String> {
|
|
||||||
let value = value.to_str().ok()?;
|
|
||||||
match value.split_once("; ") {
|
|
||||||
None => Some(value.to_string()),
|
|
||||||
Some((mime, _)) => Some(mime.to_string()),
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,11 @@
|
||||||
[package]
|
[package]
|
||||||
name = "acrate-hostmeta"
|
name = "acrate_rd"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
|
mime = "0.3.17"
|
||||||
quick-xml = { version = "0.37.0", features = ["overlapped-lists", "serialize"] }
|
quick-xml = { version = "0.37.0", features = ["overlapped-lists", "serialize"] }
|
||||||
reqwest = { version = "0.12.9", features = ["json", "stream"] }
|
reqwest = { version = "0.12.9", features = ["json", "stream"] }
|
||||||
serde = { version = "1.0.214", features = ["derive"] }
|
serde = { version = "1.0.214", features = ["derive"] }
|
|
@ -1,14 +1,18 @@
|
||||||
|
//! Definition and implementation of [`ResourceDescriptorJRD`].
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::str::FromStr;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use crate::xrd::{ResourceDescriptorLinkXRD, ResourceDescriptorPropertyXRD, ResourceDescriptorTitleXRD, ResourceDescriptorXRD};
|
use crate::xrd::{ResourceDescriptorLinkXRD, ResourceDescriptorPropertyXRD, ResourceDescriptorTitleXRD, ResourceDescriptorXRD};
|
||||||
|
|
||||||
/// A resource descriptor object in JRD format.
|
/// A resource descriptor in JRD format.
|
||||||
///
|
///
|
||||||
/// # Specification
|
/// # Specification
|
||||||
///
|
///
|
||||||
/// - <https://datatracker.ietf.org/doc/html/rfc6415#section-3>
|
/// - <https://datatracker.ietf.org/doc/html/rfc6415#section-3>
|
||||||
/// - <https://datatracker.ietf.org/doc/html/rfc7033#section-4.4>
|
/// - <https://datatracker.ietf.org/doc/html/rfc7033#section-4.4>
|
||||||
|
///
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct ResourceDescriptorJRD {
|
pub struct ResourceDescriptorJRD {
|
||||||
/// The resource this document refers to.
|
/// The resource this document refers to.
|
||||||
|
@ -72,7 +76,8 @@ pub struct ResourceDescriptorLinkJRD {
|
||||||
/// - <https://datatracker.ietf.org/doc/html/rfc7033#section-4.4.4.2>
|
/// - <https://datatracker.ietf.org/doc/html/rfc7033#section-4.4.4.2>
|
||||||
///
|
///
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub r#type: Option<String>,
|
#[serde(with = "crate::utils::serde_mime_opt")]
|
||||||
|
pub r#type: Option<mime::Mime>,
|
||||||
|
|
||||||
/// URI to the resource put in relation.
|
/// URI to the resource put in relation.
|
||||||
///
|
///
|
||||||
|
@ -123,7 +128,7 @@ impl ResourceDescriptorJRD {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # tokio_test::block_on(async {
|
/// # tokio_test::block_on(async {
|
||||||
/// use acrate_hostmeta::jrd::ResourceDescriptorJRD;
|
/// use acrate_rd::jrd::ResourceDescriptorJRD;
|
||||||
///
|
///
|
||||||
/// let client = reqwest::Client::new();
|
/// let client = reqwest::Client::new();
|
||||||
/// let url: reqwest::Url = "https://junimo.party/.well-known/nodeinfo".parse()
|
/// let url: reqwest::Url = "https://junimo.party/.well-known/nodeinfo".parse()
|
||||||
|
@ -168,14 +173,25 @@ impl ResourceDescriptorJRD {
|
||||||
.get(reqwest::header::CONTENT_TYPE)
|
.get(reqwest::header::CONTENT_TYPE)
|
||||||
.ok_or(ContentTypeMissing)?;
|
.ok_or(ContentTypeMissing)?;
|
||||||
|
|
||||||
log::trace!("Extracting MIME type from the `Content-Type` header...");
|
log::trace!("Extracting media type from the `Content-Type` header...");
|
||||||
let mime_type = crate::utils::extract_mime_from_content_type(content_type)
|
let mime_type = content_type.to_str()
|
||||||
.ok_or(ContentTypeInvalid)?;
|
.map_err(ContentTypeUnprintable)?;
|
||||||
|
|
||||||
log::trace!("Ensuring MIME type is acceptable for JRD parsing...");
|
log::trace!("Parsing media type: {mime_type:?}");
|
||||||
if !(mime_type == "application/json" || mime_type == "application/jrd+json") {
|
let mime_type = mime::Mime::from_str(mime_type)
|
||||||
|
.map_err(ContentTypeInvalid)?;
|
||||||
|
|
||||||
|
log::trace!("Checking if media type is supported...");
|
||||||
|
let mime_is_json = mime_type == mime::APPLICATION_JSON;
|
||||||
|
log::trace!("Is media type application/json? {mime_is_json:?}");
|
||||||
|
let mime_is_jrd =
|
||||||
|
mime_type.type_() == mime::APPLICATION
|
||||||
|
&& mime_type.subtype() == "jrd"
|
||||||
|
&& mime_type.suffix() == Some(mime::JSON);
|
||||||
|
log::trace!("Is media type application/jrd+json? {mime_is_jrd:?}");
|
||||||
|
if !(mime_is_json || mime_is_jrd) {
|
||||||
log::error!("MIME type `{mime_type}` is not acceptable for JRD parsing.");
|
log::error!("MIME type `{mime_type}` is not acceptable for JRD parsing.");
|
||||||
return Err(ContentTypeInvalid);
|
return Err(ContentTypeUnsupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
log::trace!("Attempting to parse response as JSON...");
|
log::trace!("Attempting to parse response as JSON...");
|
||||||
|
@ -245,9 +261,17 @@ pub enum GetJRDError {
|
||||||
#[error("the Content-Type header of the response is missing")]
|
#[error("the Content-Type header of the response is missing")]
|
||||||
ContentTypeMissing,
|
ContentTypeMissing,
|
||||||
|
|
||||||
/// The `Content-Type` header of the response is invalid.
|
/// The `Content-Type` header of the response can't be converted to a [`str`].
|
||||||
#[error("the Content-Type header of the response is invalid")]
|
#[error("the Content-Type header of the response cannot be converted to a &str")]
|
||||||
ContentTypeInvalid,
|
ContentTypeUnprintable(reqwest::header::ToStrError),
|
||||||
|
|
||||||
|
/// The `Content-Type` header of the response is not a valid [`mime::Mime`] type.
|
||||||
|
#[error("the Content-Type header of the response is not a valid media type")]
|
||||||
|
ContentTypeInvalid(mime::FromStrError),
|
||||||
|
|
||||||
|
/// The `Content-Type` header of the response is not a supported [`mime::Mime`] type.
|
||||||
|
#[error("the Content-Type header of the response is not a supported media type")]
|
||||||
|
ContentTypeUnsupported,
|
||||||
|
|
||||||
/// The document failed to be parsed as JSON by [`reqwest`].
|
/// The document failed to be parsed as JSON by [`reqwest`].
|
||||||
#[error("the document failed to be parsed as JSON")]
|
#[error("the document failed to be parsed as JSON")]
|
|
@ -1,4 +1,4 @@
|
||||||
//! Resource descriptior handler.
|
//! Rust typing and utilities for the resource descriptior format.
|
||||||
//!
|
//!
|
||||||
//! # Specification
|
//! # Specification
|
||||||
//!
|
//!
|
||||||
|
@ -8,5 +8,4 @@
|
||||||
pub mod jrd;
|
pub mod jrd;
|
||||||
pub mod xrd;
|
pub mod xrd;
|
||||||
pub mod any;
|
pub mod any;
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
105
acrate_rd/src/utils.rs
Normal file
105
acrate_rd/src/utils.rs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
//! Various utilities reused in the whole crate.
|
||||||
|
|
||||||
|
/// Module to use in `serde(with = ...)` to [`serde`] a [`mime::Mime`].
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub mod serde_mime {
|
||||||
|
use std::fmt::Formatter;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use serde::de::{Error, Visitor};
|
||||||
|
use serde::{Deserializer, Serializer};
|
||||||
|
|
||||||
|
pub struct MimeVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for MimeVisitor {
|
||||||
|
type Value = mime::Mime;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
|
||||||
|
formatter.write_str("a media type (MIME type)")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
mime::Mime::from_str(v)
|
||||||
|
.map_err(|_| E::custom("failed to parse media type"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, De>(deserializer: De) -> Result<<MimeVisitor as Visitor<'de>>::Value, De::Error>
|
||||||
|
where
|
||||||
|
De: Deserializer<'de>
|
||||||
|
{
|
||||||
|
let s = deserializer.deserialize_str(MimeVisitor)?;
|
||||||
|
Ok(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize<Ser>(data: mime::Mime, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
|
||||||
|
where
|
||||||
|
Ser: Serializer
|
||||||
|
{
|
||||||
|
let s = data.essence_str();
|
||||||
|
serializer.serialize_str(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Module to use in `serde(with = ...)` to [`serde`] an [`Option`] of [`mime::Mime`].
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub mod serde_mime_opt {
|
||||||
|
use std::fmt::Formatter;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use serde::de::{Error, Visitor};
|
||||||
|
use serde::{Deserializer, Serializer};
|
||||||
|
|
||||||
|
pub struct MimeVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for MimeVisitor {
|
||||||
|
type Value = Option<mime::Mime>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
|
||||||
|
formatter.write_str("optionally, a media type (MIME type)")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
Ok(
|
||||||
|
Some(
|
||||||
|
mime::Mime::from_str(v)
|
||||||
|
.map_err(|_| E::custom("failed to parse media type"))?
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_none<E>(self) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, De>(deserializer: De) -> Result<<MimeVisitor as Visitor<'de>>::Value, De::Error>
|
||||||
|
where
|
||||||
|
De: Deserializer<'de>
|
||||||
|
{
|
||||||
|
let s = deserializer.deserialize_str(MimeVisitor)?;
|
||||||
|
Ok(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize<Ser>(data: &Option<mime::Mime>, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
|
||||||
|
where
|
||||||
|
Ser: Serializer
|
||||||
|
{
|
||||||
|
match data {
|
||||||
|
None => {
|
||||||
|
serializer.serialize_none()
|
||||||
|
}
|
||||||
|
Some(data) => {
|
||||||
|
let s = data.essence_str();
|
||||||
|
serializer.serialize_str(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,6 @@
|
||||||
|
//! Definition and implementation of [`ResourceDescriptorXRD`].
|
||||||
|
|
||||||
|
use std::str::FromStr;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use crate::jrd::{ResourceDescriptorJRD, ResourceDescriptorLinkJRD};
|
use crate::jrd::{ResourceDescriptorJRD, ResourceDescriptorLinkJRD};
|
||||||
|
@ -79,7 +82,8 @@ pub struct ResourceDescriptorLinkXRD {
|
||||||
///
|
///
|
||||||
#[serde(rename = "@type")]
|
#[serde(rename = "@type")]
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub r#type: Option<String>,
|
#[serde(with = "crate::utils::serde_mime_opt")]
|
||||||
|
pub r#type: Option<mime::Mime>,
|
||||||
|
|
||||||
/// URI to the resource put in relation.
|
/// URI to the resource put in relation.
|
||||||
///
|
///
|
||||||
|
@ -163,7 +167,7 @@ impl ResourceDescriptorXRD {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # tokio_test::block_on(async {
|
/// # tokio_test::block_on(async {
|
||||||
/// use acrate_hostmeta::xrd::ResourceDescriptorXRD;
|
/// use acrate_rd::xrd::ResourceDescriptorXRD;
|
||||||
///
|
///
|
||||||
/// let client = reqwest::Client::new();
|
/// let client = reqwest::Client::new();
|
||||||
/// let url: reqwest::Url = "https://junimo.party/.well-known/host-meta".parse()
|
/// let url: reqwest::Url = "https://junimo.party/.well-known/host-meta".parse()
|
||||||
|
@ -205,14 +209,23 @@ impl ResourceDescriptorXRD {
|
||||||
.get(reqwest::header::CONTENT_TYPE)
|
.get(reqwest::header::CONTENT_TYPE)
|
||||||
.ok_or(ContentTypeMissing)?;
|
.ok_or(ContentTypeMissing)?;
|
||||||
|
|
||||||
log::trace!("Extracting MIME type from the `Content-Type` header...");
|
log::trace!("Extracting media type from the `Content-Type` header...");
|
||||||
let mime_type = crate::utils::extract_mime_from_content_type(content_type)
|
let mime_type = content_type.to_str()
|
||||||
.ok_or(ContentTypeInvalid)?;
|
.map_err(ContentTypeUnprintable)?;
|
||||||
|
|
||||||
log::trace!("Ensuring MIME type is acceptable for XRD parsing...");
|
log::trace!("Parsing media type: {mime_type:?}");
|
||||||
if mime_type != "application/xrd+xml" {
|
let mime_type = mime::Mime::from_str(mime_type)
|
||||||
log::error!("MIME type `{mime_type}` is not acceptable for XRD parsing.");
|
.map_err(ContentTypeInvalid)?;
|
||||||
return Err(ContentTypeInvalid)
|
|
||||||
|
log::trace!("Checking if media type is supported...");
|
||||||
|
let mime_is_xrd =
|
||||||
|
mime_type.type_() == mime::APPLICATION
|
||||||
|
&& mime_type.subtype() == "xrd"
|
||||||
|
&& mime_type.suffix() == Some(mime::XML);
|
||||||
|
log::trace!("Is media type application/xrd+xml? {mime_is_xrd:?}");
|
||||||
|
if !mime_is_xrd {
|
||||||
|
log::error!("MIME type `{mime_type}` is not acceptable for JRD parsing.");
|
||||||
|
return Err(ContentTypeUnsupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
log::trace!("Attempting to parse response as text...");
|
log::trace!("Attempting to parse response as text...");
|
||||||
|
@ -290,9 +303,17 @@ pub enum GetXRDError {
|
||||||
#[error("the Content-Type header of the response is missing")]
|
#[error("the Content-Type header of the response is missing")]
|
||||||
ContentTypeMissing,
|
ContentTypeMissing,
|
||||||
|
|
||||||
/// The `Content-Type` header of the response is invalid.
|
/// The `Content-Type` header of the response can't be converted to a [`str`].
|
||||||
#[error("the Content-Type header of the response is invalid")]
|
#[error("the Content-Type header of the response cannot be converted to a &str")]
|
||||||
ContentTypeInvalid,
|
ContentTypeUnprintable(reqwest::header::ToStrError),
|
||||||
|
|
||||||
|
/// The `Content-Type` header of the response is not a valid [`mime::Mime`] type.
|
||||||
|
#[error("the Content-Type header of the response is not a valid media type")]
|
||||||
|
ContentTypeInvalid(mime::FromStrError),
|
||||||
|
|
||||||
|
/// The `Content-Type` header of the response is not a supported [`mime::Mime`] type.
|
||||||
|
#[error("the Content-Type header of the response is not a supported media type")]
|
||||||
|
ContentTypeUnsupported,
|
||||||
|
|
||||||
/// The document failed to be decoded as text.
|
/// The document failed to be decoded as text.
|
||||||
#[error("the document failed to be decoded as text")]
|
#[error("the document failed to be decoded as text")]
|
|
@ -38,7 +38,7 @@ macro_rules! test_discover_hostmeta {
|
||||||
let base: reqwest::Url = $url.parse()
|
let base: reqwest::Url = $url.parse()
|
||||||
.expect("a valid URL");
|
.expect("a valid URL");
|
||||||
|
|
||||||
let doc = acrate_hostmeta::any::ResourceDescriptor::discover_hostmeta(&client, base)
|
let doc = acrate_rd::any::ResourceDescriptor::discover_hostmeta(&client, base)
|
||||||
.await
|
.await
|
||||||
.expect("host-meta discovery to succeed");
|
.expect("host-meta discovery to succeed");
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ macro_rules! test_de_ser_jrd {
|
||||||
|
|
||||||
log::info!("Starting document: {:#?}", JRD_DOCUMENT);
|
log::info!("Starting document: {:#?}", JRD_DOCUMENT);
|
||||||
|
|
||||||
let de: acrate_hostmeta::jrd::ResourceDescriptorJRD = serde_json::from_str(JRD_DOCUMENT)
|
let de: acrate_rd::jrd::ResourceDescriptorJRD = serde_json::from_str(JRD_DOCUMENT)
|
||||||
.expect("document to be deserialized successfully");
|
.expect("document to be deserialized successfully");
|
||||||
|
|
||||||
log::info!("Serialized document: {de:#?}");
|
log::info!("Serialized document: {de:#?}");
|
||||||
|
@ -85,11 +85,10 @@ macro_rules! test_de_ser_xrd {
|
||||||
$(#[$tag])*
|
$(#[$tag])*
|
||||||
fn $id() {
|
fn $id() {
|
||||||
init_log();
|
init_log();
|
||||||
let client = make_client();
|
|
||||||
|
|
||||||
log::info!("Starting document: {:#?}", XRD_DOCUMENT);
|
log::info!("Starting document: {:#?}", XRD_DOCUMENT);
|
||||||
|
|
||||||
let de: acrate_hostmeta::xrd::ResourceDescriptorXRD = quick_xml::de::from_str(XRD_DOCUMENT)
|
let de: acrate_rd::xrd::ResourceDescriptorXRD = quick_xml::de::from_str(XRD_DOCUMENT)
|
||||||
.expect("document to be deserialized successfully");
|
.expect("document to be deserialized successfully");
|
||||||
|
|
||||||
log::info!("Serialized document: {de:#?}");
|
log::info!("Serialized document: {de:#?}");
|
||||||
|
@ -113,4 +112,5 @@ test_discover_hostmeta!(test_discover_hostmeta_threads_net, "https://threads.net
|
||||||
test_discover_hostmeta!(test_discover_hostmeta_ngoa_giao_loan, "https://ngoa.giao.loan", ignore = "does not support host-meta");
|
test_discover_hostmeta!(test_discover_hostmeta_ngoa_giao_loan, "https://ngoa.giao.loan", ignore = "does not support host-meta");
|
||||||
test_discover_hostmeta!(test_discover_hostmeta_hollo_social, "https://hollo.social", ignore = "does not support host-meta");
|
test_discover_hostmeta!(test_discover_hostmeta_hollo_social, "https://hollo.social", ignore = "does not support host-meta");
|
||||||
|
|
||||||
test_de_ser_jrd!(test_de_ser_sample_junimo_party, "samples/junimo_party.nodeinfo.jrd.json");
|
test_de_ser_jrd!(test_de_ser_jrd_sample_junimo_party, "samples/junimo_party.nodeinfo.jrd.json");
|
||||||
|
test_de_ser_xrd!(test_de_ser_xrd_sample_junimo_party, "samples/junimo_party.host-meta.xrd.xml");
|
Loading…
Reference in a new issue