atproto blogging
1use http::Uri;
2use smol_str::SmolStr;
3use weaver_common::jacquard::types::string::{Cid, Did};
4
5pub struct Link<'a> {
6 pub uri: Uri,
7 pub blob: BlobLink<'a>,
8}
9
10pub type MimeType = SmolStr;
11
12pub enum BlobLink<'a> {
13 PDS {
14 pds_host: String,
15 did: Did<'a>,
16 cid: Cid<'a>,
17 mime_type: MimeType,
18 },
19 BskyCdn(CdnLink<'a>),
20 WeaverCdn(CdnLink<'a>),
21}
22
23pub enum CdnLink<'a> {
24 Avatar(Did<'a>, Cid<'a>, MimeType),
25 Banner(Did<'a>, Cid<'a>, MimeType),
26 Thumbnail(Did<'a>, Cid<'a>, MimeType),
27 PostImage(Did<'a>, Cid<'a>, MimeType),
28 EmbedImage(Did<'a>, Cid<'a>, MimeType),
29}
30
31impl std::fmt::Display for BlobLink<'_> {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 match self {
34 BlobLink::PDS {
35 pds_host,
36 did,
37 cid,
38 mime_type: _,
39 } => {
40 write!(
41 f,
42 "{}/xrpc/com.atproto.sync.getBlob?did={}&cid={}",
43 pds_host,
44 did.as_str(),
45 cid.as_ref()
46 )
47 }
48 _ => write!(
49 f,
50 "{}{}/{}@{}",
51 self.url_prefix(),
52 self.did().as_str(),
53 self.cid().as_ref(),
54 self.mime_type().rsplit('/').next().unwrap()
55 ),
56 }
57 }
58}
59
60impl<'a> BlobLink<'a> {
61 #[inline]
62 pub fn url_prefix(&self) -> &str {
63 match self {
64 BlobLink::PDS { pds_host, .. } => pds_host,
65 BlobLink::BskyCdn(CdnLink::Avatar(..)) => "https://cdn.bsky.app/img/avatar/plain/",
66 BlobLink::BskyCdn(CdnLink::Banner(..)) => "https://cdn.bsky.app/img/banner/plain/",
67 BlobLink::BskyCdn(CdnLink::Thumbnail(..)) => {
68 "https://cdn.bsky.app/img/feed_thumbnail/plain/"
69 }
70 BlobLink::BskyCdn(CdnLink::PostImage(..)) => {
71 "https://cdn.bsky.app/img/feed_fullsize/plain/"
72 }
73 BlobLink::BskyCdn(CdnLink::EmbedImage(..)) => {
74 "https://cdn.bsky.app/img/feed_fullsize/plain/"
75 }
76 BlobLink::WeaverCdn(CdnLink::Avatar(..)) => "https://cdn.weaver.sh/img/avatar/",
77 BlobLink::WeaverCdn(CdnLink::Banner(..)) => "https://cdn.weaver.sh/img/full/",
78 BlobLink::WeaverCdn(CdnLink::Thumbnail(..)) => "https://cdn.weaver.sh/img/thumbnail/",
79 BlobLink::WeaverCdn(CdnLink::PostImage(..)) => "https://cdn.weaver.sh/img/full/",
80 BlobLink::WeaverCdn(CdnLink::EmbedImage(..)) => "https://cdn.weaver.sh/img/embed/",
81 }
82 }
83
84 #[inline]
85 pub const fn did(&self) -> &Did<'a> {
86 match self {
87 BlobLink::PDS { did, .. } => did,
88 BlobLink::BskyCdn(CdnLink::Avatar(did, ..))
89 | BlobLink::BskyCdn(CdnLink::Banner(did, ..))
90 | BlobLink::BskyCdn(CdnLink::Thumbnail(did, ..))
91 | BlobLink::BskyCdn(CdnLink::PostImage(did, ..))
92 | BlobLink::BskyCdn(CdnLink::EmbedImage(did, ..)) => did,
93 BlobLink::WeaverCdn(CdnLink::Avatar(did, ..))
94 | BlobLink::WeaverCdn(CdnLink::Banner(did, ..))
95 | BlobLink::WeaverCdn(CdnLink::Thumbnail(did, ..))
96 | BlobLink::WeaverCdn(CdnLink::PostImage(did, ..))
97 | BlobLink::WeaverCdn(CdnLink::EmbedImage(did, ..)) => did,
98 }
99 }
100
101 #[inline]
102 pub const fn cid(&self) -> &Cid<'a> {
103 match self {
104 BlobLink::PDS { cid, .. } => cid,
105 BlobLink::BskyCdn(CdnLink::Avatar(_, cid, ..))
106 | BlobLink::BskyCdn(CdnLink::Banner(_, cid, ..))
107 | BlobLink::BskyCdn(CdnLink::Thumbnail(_, cid, ..))
108 | BlobLink::BskyCdn(CdnLink::PostImage(_, cid, ..))
109 | BlobLink::BskyCdn(CdnLink::EmbedImage(_, cid, ..)) => cid,
110 BlobLink::WeaverCdn(CdnLink::Avatar(_, cid, ..))
111 | BlobLink::WeaverCdn(CdnLink::Banner(_, cid, ..))
112 | BlobLink::WeaverCdn(CdnLink::Thumbnail(_, cid, ..))
113 | BlobLink::WeaverCdn(CdnLink::PostImage(_, cid, ..))
114 | BlobLink::WeaverCdn(CdnLink::EmbedImage(_, cid, ..)) => cid,
115 }
116 }
117
118 #[inline]
119 pub const fn mime_type(&self) -> &MimeType {
120 match self {
121 BlobLink::PDS { mime_type, .. } => mime_type,
122 BlobLink::BskyCdn(CdnLink::Avatar(_, _, mime_type))
123 | BlobLink::BskyCdn(CdnLink::Banner(_, _, mime_type))
124 | BlobLink::BskyCdn(CdnLink::Thumbnail(_, _, mime_type))
125 | BlobLink::BskyCdn(CdnLink::PostImage(_, _, mime_type))
126 | BlobLink::BskyCdn(CdnLink::EmbedImage(_, _, mime_type)) => mime_type,
127 BlobLink::WeaverCdn(CdnLink::Avatar(_, _, mime_type))
128 | BlobLink::WeaverCdn(CdnLink::Banner(_, _, mime_type))
129 | BlobLink::WeaverCdn(CdnLink::Thumbnail(_, _, mime_type))
130 | BlobLink::WeaverCdn(CdnLink::PostImage(_, _, mime_type))
131 | BlobLink::WeaverCdn(CdnLink::EmbedImage(_, _, mime_type)) => mime_type,
132 }
133 }
134}