mirror of
https://github.com/versia-pub/activitypub.git
synced 2026-03-13 10:59:17 +01:00
feat: lysand user
This commit is contained in:
parent
9e6445d192
commit
eec3a037bb
7 changed files with 369 additions and 22 deletions
|
|
@ -1 +1,3 @@
|
|||
pub mod objects;
|
||||
pub mod superx;
|
||||
pub mod test;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,135 @@
|
|||
extern crate serde; // 1.0.68
|
||||
extern crate serde_derive; // 1.0.68
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::{Display, Formatter},
|
||||
};
|
||||
|
||||
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use time::{
|
||||
format_description::well_known::{iso8601, Iso8601},
|
||||
OffsetDateTime,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
pub enum LysandType {
|
||||
User,
|
||||
const FORMAT: Iso8601<6651332276412969266533270467398074368> = Iso8601::<
|
||||
{
|
||||
iso8601::Config::DEFAULT
|
||||
.set_year_is_six_digits(false)
|
||||
.encode()
|
||||
},
|
||||
>;
|
||||
time::serde::format_description!(iso_lysand, OffsetDateTime, FORMAT);
|
||||
|
||||
fn sort_alphabetically<T: Serialize, S: serde::Serializer>(
|
||||
value: &T,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
let value = serde_json::to_value(value).map_err(serde::ser::Error::custom)?;
|
||||
value.serialize(serializer)
|
||||
}
|
||||
|
||||
pub struct User {
|
||||
#[derive(Serialize)]
|
||||
pub struct SortAlphabetically<T: Serialize>(#[serde(serialize_with = "sort_alphabetically")] pub T);
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub enum LysandType {
|
||||
User,
|
||||
Note,
|
||||
Patch,
|
||||
Like,
|
||||
Dislike,
|
||||
Follow,
|
||||
FollowAccept,
|
||||
FollowReject,
|
||||
Undo,
|
||||
Extension,
|
||||
ServerMetadata,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct PublicKey {
|
||||
public_key: String,
|
||||
actor: Url,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct ContentHash {
|
||||
md5: Option<String>,
|
||||
sha1: Option<String>,
|
||||
sha256: Option<String>,
|
||||
sha512: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct ContentFormat {
|
||||
x: HashMap<String, ContentEntry>,
|
||||
}
|
||||
|
||||
impl Serialize for ContentFormat {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_map(Some(self.x.len()))?;
|
||||
for (k, v) in &self.x {
|
||||
seq.serialize_entry(&k.to_string(), &v)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
impl<'de> Deserialize<'de> for ContentFormat {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let map = HashMap::deserialize(deserializer)?;
|
||||
Ok(ContentFormat { x: map })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
struct FieldKV {
|
||||
key: ContentFormat,
|
||||
value: ContentFormat,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct ContentEntry {
|
||||
content: String,
|
||||
description: Option<String>,
|
||||
size: Option<u64>,
|
||||
hash: Option<ContentHash>,
|
||||
blurhash: Option<String>,
|
||||
fps: Option<u64>,
|
||||
width: Option<u64>,
|
||||
height: Option<u64>,
|
||||
duration: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct User {
|
||||
public_key: PublicKey,
|
||||
#[serde(rename = "type")]
|
||||
rtype: LysandType,
|
||||
id: String,
|
||||
uri: Url,
|
||||
created_at: String,
|
||||
#[serde(with = "iso_lysand")]
|
||||
created_at: OffsetDateTime,
|
||||
display_name: Option<String>,
|
||||
// TODO bio: Option<String>,
|
||||
inbox: Url,
|
||||
outbox: Url,
|
||||
featured: Url,
|
||||
followers: Url,
|
||||
following: Url,
|
||||
likes: Url,
|
||||
dislikes: Url,
|
||||
username: String,
|
||||
bio: Option<ContentFormat>,
|
||||
avatar: Option<ContentFormat>,
|
||||
header: Option<ContentFormat>,
|
||||
fields: Option<Vec<FieldKV>>,
|
||||
}
|
||||
|
|
|
|||
35
src/lysand/superx.rs
Normal file
35
src/lysand/superx.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
use super::objects::SortAlphabetically;
|
||||
|
||||
pub async fn deserialize_user(data: String) -> anyhow::Result<super::objects::User> {
|
||||
let user: super::objects::User = serde_json::from_str(&data)?;
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
pub async fn serialize_user(user: super::objects::User) -> anyhow::Result<String> {
|
||||
let data = serde_json::to_string(&SortAlphabetically(&user))?;
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
pub async fn deserialize_lysand_type(data: String) -> anyhow::Result<super::objects::LysandType> {
|
||||
let lysand_type: super::objects::LysandType = serde_json::from_str(&data)?;
|
||||
Ok(lysand_type)
|
||||
}
|
||||
|
||||
pub async fn serialize_lysand_type(
|
||||
lysand_type: super::objects::LysandType,
|
||||
) -> anyhow::Result<String> {
|
||||
let data = serde_json::to_string(&lysand_type)?;
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn request_client() -> reqwest::Client {
|
||||
reqwest::Client::builder()
|
||||
.user_agent(concat!(
|
||||
env!("CARGO_PKG_NAME"),
|
||||
"/",
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
))
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
26
src/lysand/test.rs
Normal file
26
src/lysand/test.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
use crate::lysand::objects::SortAlphabetically;
|
||||
|
||||
use super::superx::request_client;
|
||||
|
||||
pub async fn main() -> anyhow::Result<()> {
|
||||
let client = request_client();
|
||||
|
||||
println!("Requesting user");
|
||||
let response = client
|
||||
.get("https://social.lysand.org/users/018ec082-0ae1-761c-b2c5-22275a611771")
|
||||
.send()
|
||||
.await?;
|
||||
println!("Response: {:?}", response);
|
||||
let user_json = response.text().await?;
|
||||
println!("User JSON: {:?}", user_json);
|
||||
let user = super::superx::deserialize_user(user_json).await?;
|
||||
|
||||
println!("\n\n\nUser: ");
|
||||
print!("{:#?}", user);
|
||||
|
||||
println!("\n\n\nas JSON:");
|
||||
let user_json = serde_json::to_string_pretty(&SortAlphabetically(&user))?;
|
||||
println!("{}", user_json);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -149,6 +149,10 @@ static FEDERATION_CONFIG: OnceLock<FederationConfig<State>> = OnceLock::new();
|
|||
async fn main() -> actix_web::Result<(), anyhow::Error> {
|
||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||
|
||||
//TODO remove this
|
||||
lysand::test::main().await?;
|
||||
return Ok(());
|
||||
|
||||
let ap_id = Url::parse(&format!(
|
||||
"https://{}/{}",
|
||||
DOMAIN.to_string(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue