about summary refs log tree commit diff
path: root/src/webmentions/check.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/webmentions/check.rs')
-rw-r--r--src/webmentions/check.rs52
1 files changed, 38 insertions, 14 deletions
diff --git a/src/webmentions/check.rs b/src/webmentions/check.rs
index 683cc6b..380f4db 100644
--- a/src/webmentions/check.rs
+++ b/src/webmentions/check.rs
@@ -1,7 +1,7 @@
-use std::rc::Rc;
-use microformats::types::PropertyValue;
 use html5ever::{self, tendril::TendrilSink};
 use kittybox_util::MentionType;
+use microformats::types::PropertyValue;
+use std::rc::Rc;
 
 // TODO: replace.
 mod rcdom;
@@ -17,7 +17,11 @@ pub enum Error {
 }
 
 #[tracing::instrument]
-pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url::Url, link: &url::Url) -> Result<Option<(MentionType, serde_json::Value)>, Error> {
+pub fn check_mention(
+    document: impl AsRef<str> + std::fmt::Debug,
+    base_url: &url::Url,
+    link: &url::Url,
+) -> Result<Option<(MentionType, serde_json::Value)>, Error> {
     tracing::debug!("Parsing MF2 markup...");
     // First, check the document for MF2 markup
     let document = microformats::from_html(document.as_ref(), base_url.clone())?;
@@ -29,8 +33,10 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url
         tracing::debug!("Processing item: {:?}", item);
 
         for (prop, interaction_type) in [
-            ("in-reply-to", MentionType::Reply), ("like-of", MentionType::Like),
-            ("bookmark-of", MentionType::Bookmark), ("repost-of", MentionType::Repost)
+            ("in-reply-to", MentionType::Reply),
+            ("like-of", MentionType::Like),
+            ("bookmark-of", MentionType::Bookmark),
+            ("repost-of", MentionType::Repost),
         ] {
             if let Some(propvals) = item.properties.get(prop) {
                 tracing::debug!("Has a u-{} property", prop);
@@ -38,7 +44,10 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url
                     if let PropertyValue::Url(url) = val {
                         if url == link {
                             tracing::debug!("URL matches! Webmention is valid");
-                            return Ok(Some((interaction_type, serde_json::to_value(item).unwrap())))
+                            return Ok(Some((
+                                interaction_type,
+                                serde_json::to_value(item).unwrap(),
+                            )));
                         }
                     }
                 }
@@ -46,7 +55,9 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url
         }
         // Process `content`
         tracing::debug!("Processing e-content...");
-        if let Some(PropertyValue::Fragment(content)) = item.properties.get("content")
+        if let Some(PropertyValue::Fragment(content)) = item
+            .properties
+            .get("content")
             .map(Vec::as_slice)
             .unwrap_or_default()
             .first()
@@ -65,7 +76,8 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url
             // iteration of the loop.
             //
             // Empty list means all nodes were processed.
-            let mut unprocessed_nodes: Vec<Rc<rcdom::Node>> = root.children.borrow().iter().cloned().collect();
+            let mut unprocessed_nodes: Vec<Rc<rcdom::Node>> =
+                root.children.borrow().iter().cloned().collect();
             while !unprocessed_nodes.is_empty() {
                 // "Take" the list out of its memory slot, replace it with an empty list
                 let nodes = std::mem::take(&mut unprocessed_nodes);
@@ -74,15 +86,23 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url
                     // Add children nodes to the list for the next iteration
                     unprocessed_nodes.extend(node.children.borrow().iter().cloned());
 
-                    if let rcdom::NodeData::Element { ref name, ref attrs, .. } = node.data {
+                    if let rcdom::NodeData::Element {
+                        ref name,
+                        ref attrs,
+                        ..
+                    } = node.data
+                    {
                         // If it's not `<a>`, skip it
-                        if name.local != *"a" { continue; }
+                        if name.local != *"a" {
+                            continue;
+                        }
                         let mut is_mention: bool = false;
                         for attr in attrs.borrow().iter() {
                             if attr.name.local == *"rel" {
                                 // Don't count `rel="nofollow"` links — a web crawler should ignore them
                                 // and so for purposes of driving visitors they are useless
-                                if attr.value
+                                if attr
+                                    .value
                                     .as_ref()
                                     .split([',', ' '])
                                     .any(|v| v == "nofollow")
@@ -92,7 +112,9 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url
                                 }
                             }
                             // if it's not `<a href="...">`, skip it
-                            if attr.name.local != *"href" { continue; }
+                            if attr.name.local != *"href" {
+                                continue;
+                            }
                             // Be forgiving in parsing URLs, and resolve them against the base URL
                             if let Ok(url) = base_url.join(attr.value.as_ref()) {
                                 if &url == link {
@@ -101,12 +123,14 @@ pub fn check_mention(document: impl AsRef<str> + std::fmt::Debug, base_url: &url
                             }
                         }
                         if is_mention {
-                            return Ok(Some((MentionType::Mention, serde_json::to_value(item).unwrap())));
+                            return Ok(Some((
+                                MentionType::Mention,
+                                serde_json::to_value(item).unwrap(),
+                            )));
                         }
                     }
                 }
             }
-
         }
     }