mastodon.rs
1 use anyhow::Context; 2 use log::debug; 3 use serde::Deserialize; 4 use serde_aux::field_attributes::deserialize_number_from_string; 5 use url::Url; 6 7 use crate::http::{self, RequestBuilderExt}; 8 9 pub fn lookup_account(base_url: &Url, name: &str) -> anyhow::Result<Account> { 10 debug!("fetching account info for {name} on {base_url}"); 11 http::client() 12 .get( 13 base_url 14 .join("api/v1/accounts/lookup") 15 .context("creating url")?, 16 ) 17 .query(&[("acct", name)]) 18 .execute() 19 .context("fetching") 20 } 21 22 pub fn fetch_posts( 23 base_url: &Url, 24 account_id: &Id, 25 min_id: &Id, 26 limit: u16, 27 exclude_reblogs: bool, 28 ) -> anyhow::Result<Vec<Post>> { 29 http::client() 30 .get( 31 base_url 32 .join(&format!("api/v1/accounts/{}/statuses", account_id.0)) 33 .context("creating url")?, 34 ) 35 .query(&[("min_id", min_id.0)]) 36 .query(&[("limit", limit)]) 37 .query(&[("exclude_reblogs", exclude_reblogs)]) 38 .execute() 39 .context("fetching") 40 } 41 42 #[derive(Deserialize, Debug)] 43 pub struct Post { 44 pub id: Id, 45 pub url: Url, 46 pub created_at: String, 47 pub sensitive: bool, 48 pub content: String, 49 pub media_attachments: Vec<MediaAttachment>, 50 pub account: Account, 51 } 52 53 #[derive(Deserialize, Debug)] 54 pub struct Account { 55 pub id: Id, 56 pub username: String, 57 pub display_name: String, 58 pub url: Url, 59 pub avatar: Url, 60 } 61 62 #[derive(Deserialize, Debug)] 63 pub struct MediaAttachment { 64 pub id: Id, 65 #[serde(rename = "type")] 66 pub type_: AttachmentType, 67 pub url: Url, 68 } 69 70 #[derive(Deserialize, Debug)] 71 #[serde(rename_all = "lowercase")] 72 pub enum AttachmentType { 73 Unknown, 74 Image, 75 Gifv, 76 Video, 77 Audio, 78 } 79 80 #[derive(Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] 81 #[repr(transparent)] 82 pub struct Id(#[serde(deserialize_with = "deserialize_number_from_string")] pub u64);