From ca838cfaa1918d8760c397792e37706fc99e89a0 Mon Sep 17 00:00:00 2001 From: Glyn Normington Date: Wed, 5 Jun 2024 04:12:56 +0100 Subject: [PATCH] Initial filtering code --- Cargo.lock | 1 + Cargo.toml | 1 + src/jrdmap.rs | 26 +++++++++++++++++++++++++- src/main.rs | 8 +++++++- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a29f381..9cbd06d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -715,6 +715,7 @@ version = "0.1.0" dependencies = [ "axum", "clap", + "http", "serde", "serde_json", "tokio", diff --git a/Cargo.toml b/Cargo.toml index d26693a..9e46602 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] axum = "0.7.4" clap = { version = "4.5.4", features = ["derive"] } +http = "1.1.0" serde = { version = "1.0.203", features = ["derive"] } serde_json = "1.0.117" tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread"] } \ No newline at end of file diff --git a/src/jrdmap.rs b/src/jrdmap.rs index 02ef53a..b99d91d 100644 --- a/src/jrdmap.rs +++ b/src/jrdmap.rs @@ -10,7 +10,9 @@ licensed under the GPL. use std::collections::hash_map::HashMap; use std::option::Option; +use std::str::FromStr; +use http::uri::Uri; use serde; use serde_json; @@ -28,6 +30,7 @@ pub struct Jrd { // The "aliases" array is an array of zero or more URI strings that // identify the same entity as the "subject" URI. + #[serde(skip_serializing_if = "Option::is_none")] pub aliases: Option>, @@ -35,14 +38,31 @@ pub struct Jrd { // names are URIs (referred to as "property identifiers") and whose // values are strings or null. Properties are used to convey additional // information about the subject of the JRD. + #[serde(skip_serializing_if = "Option::is_none")] pub properties: Option>, // The "links" array has any number of member objects, each of which // represents a link [4]. + #[serde(skip_serializing_if = "Option::is_none")] pub links: Option>, } +impl Jrd { + pub fn filter(&self, rel: String) -> Jrd { + Jrd { + subject: self.subject.clone(), + aliases: self.aliases.clone(), + properties: self.properties.clone(), + links: self.links.clone(). + map(|lks| lks.into_iter(). + filter(|lk| Uri::from_str(&lk.rel).unwrap() == Uri::from_str(&rel).unwrap()). + collect() + ) + } + } +} + #[derive(Clone, serde::Deserialize, serde::Serialize)] pub struct ResourceLink { // Each of these link objects can have the following members: @@ -63,11 +83,13 @@ pub struct ResourceLink { // The value of the "type" member is a string that indicates the media // type of the target resource (see RFC 6838). + #[serde(skip_serializing_if = "Option::is_none")] pub type_: Option, // The value of the "href" member is a string that contains a URI // pointing to the target resource. + #[serde(skip_serializing_if = "Option::is_none")] pub href: Option, @@ -78,6 +100,7 @@ pub struct ResourceLink { // utilize the link relation, and, if used, a language identifier SHOULD // be duly used as the name. If the language is unknown or unspecified, // then the name is "und". + #[serde(skip_serializing_if = "Option::is_none")] pub titles: Option>, @@ -86,11 +109,12 @@ pub struct ResourceLink { // "property identifiers") and whose values are strings or null. // Properties are used to convey additional information about the link // relation. + #[serde(skip_serializing_if = "Option::is_none")] pub properties: Option>, } -pub fn to_json(resource : &JrdMap) -> String { +pub fn to_json(resource : &Jrd) -> String { serde_json::to_string(&resource).unwrap() } diff --git a/src/main.rs b/src/main.rs index c7b819d..81c10b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -73,5 +73,11 @@ async fn handler( ) -> String { // use `state`... - jrdmap::to_json(&state.webfinger_jrdmap) + let uri = "acct:glyn@underlap.org".to_string(); + + let jrd = state.webfinger_jrdmap.get(&uri).expect("No JRD found for input URI"); + + let rel = "http://webfinger.net/rel/avatar".to_string(); + + jrdmap::to_json(&jrd.filter(rel)) } \ No newline at end of file