Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm
1use fluent_uri::Uri; 2 3pub mod at_uri; 4pub mod did; 5pub mod record; 6 7pub use record::collect_links; 8 9#[derive(Debug, Clone, Ord, Eq, PartialOrd, PartialEq)] 10pub enum Link { 11 AtUri(String), 12 Uri(String), 13 Did(String), 14} 15 16impl Link { 17 pub fn into_string(self) -> String { 18 match self { 19 Link::AtUri(s) => s, 20 Link::Uri(s) => s, 21 Link::Did(s) => s, 22 } 23 } 24 pub fn as_str(&self) -> &str { 25 match self { 26 Link::AtUri(s) => s, 27 Link::Uri(s) => s, 28 Link::Did(s) => s, 29 } 30 } 31 pub fn name(&self) -> &'static str { 32 match self { 33 Link::AtUri(_) => "at-uri", 34 Link::Uri(_) => "uri", 35 Link::Did(_) => "did", 36 } 37 } 38 pub fn at_uri_collection(&self) -> Option<String> { 39 if let Link::AtUri(at_uri) = self { 40 at_uri::at_uri_collection(at_uri) 41 } else { 42 None 43 } 44 } 45} 46 47#[derive(Debug, PartialEq)] 48pub struct CollectedLink { 49 pub path: String, 50 pub target: Link, 51} 52 53// normalizing is a bit opinionated but eh 54pub fn parse_uri(s: &str) -> Option<String> { 55 Uri::parse(s).map(|u| u.normalize().into_string()).ok() 56} 57 58pub fn parse_any_link(s: &str) -> Option<Link> { 59 at_uri::parse_at_uri(s).map(Link::AtUri).or_else(|| { 60 did::parse_did(s) 61 .map(Link::Did) 62 .or_else(|| parse_uri(s).map(Link::Uri)) 63 }) 64} 65 66#[cfg(test)] 67mod tests { 68 use super::*; 69 70 #[test] 71 fn test_uri_parse() { 72 let s = "https://example.com"; 73 let uri = parse_uri(s).unwrap(); 74 assert_eq!(uri.as_str(), s); 75 } 76 77 #[test] 78 fn test_uri_normalizes() { 79 let s = "HTTPS://example.com/../"; 80 let uri = parse_uri(s).unwrap(); 81 assert_eq!(uri.as_str(), "https://example.com/"); 82 } 83 84 #[test] 85 fn test_uri_invalid() { 86 assert!(parse_uri("https:\\bad-example.com").is_none()); 87 } 88 89 #[test] 90 fn test_any_parse() { 91 assert_eq!( 92 parse_any_link("https://example.com"), 93 Some(Link::Uri("https://example.com".into())) 94 ); 95 96 assert_eq!( 97 parse_any_link( 98 "at://did:plc:44ybard66vv44zksje25o7dz/app.bsky.feed.post/3jwdwj2ctlk26" 99 ), 100 Some(Link::AtUri( 101 "at://did:plc:44ybard66vv44zksje25o7dz/app.bsky.feed.post/3jwdwj2ctlk26".into() 102 )), 103 ); 104 105 assert_eq!( 106 parse_any_link("did:plc:44ybard66vv44zksje25o7dz"), 107 Some(Link::Did("did:plc:44ybard66vv44zksje25o7dz".into())) 108 ) 109 } 110 111 #[test] 112 fn test_at_uri_collection() { 113 assert_eq!( 114 parse_any_link("https://example.com") 115 .unwrap() 116 .at_uri_collection(), 117 None 118 ); 119 assert_eq!( 120 parse_any_link("did:web:bad-example.com") 121 .unwrap() 122 .at_uri_collection(), 123 None 124 ); 125 assert_eq!( 126 parse_any_link("at://did:web:bad-example.com/my.collection/3jwdwj2ctlk26") 127 .unwrap() 128 .at_uri_collection(), 129 Some("my.collection".into()) 130 ); 131 } 132}