2020-04-22 20:38:22 +02:00
|
|
|
use super::err;
|
|
|
|
use super::Payload;
|
|
|
|
use crate::Id;
|
2020-04-11 04:36:03 +02:00
|
|
|
|
|
|
|
use std::convert::TryFrom;
|
|
|
|
|
|
|
|
use hashbrown::HashSet;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use serde_json::Value;
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
|
|
|
pub struct DynEvent {
|
|
|
|
#[serde(skip)]
|
2020-04-21 22:39:31 +02:00
|
|
|
pub(crate) kind: EventKind,
|
|
|
|
pub(crate) event: String,
|
|
|
|
pub(crate) payload: Value,
|
|
|
|
pub(crate) queued_at: Option<i64>,
|
2020-04-11 04:36:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2020-04-21 22:39:31 +02:00
|
|
|
pub(crate) enum EventKind {
|
2020-04-11 04:36:03 +02:00
|
|
|
Update(DynStatus),
|
|
|
|
NonUpdate,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for EventKind {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::NonUpdate
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2020-04-21 22:39:31 +02:00
|
|
|
pub(crate) struct DynStatus {
|
|
|
|
pub(crate) id: Id,
|
|
|
|
pub(crate) username: String,
|
|
|
|
pub(crate) language: Option<String>,
|
|
|
|
pub(crate) mentioned_users: HashSet<Id>,
|
|
|
|
pub(crate) replied_to_user: Option<Id>,
|
|
|
|
pub(crate) boosted_user: Option<Id>,
|
2020-04-11 04:36:03 +02:00
|
|
|
}
|
|
|
|
|
2020-04-22 20:38:22 +02:00
|
|
|
type Result<T> = std::result::Result<T, err::Event>;
|
2020-04-11 04:36:03 +02:00
|
|
|
|
|
|
|
impl DynEvent {
|
2020-04-21 22:39:31 +02:00
|
|
|
pub(crate) fn set_update(self) -> Result<Self> {
|
2020-04-11 04:36:03 +02:00
|
|
|
if self.event == "update" {
|
2020-04-15 02:37:49 +02:00
|
|
|
let kind = EventKind::Update(DynStatus::new(&self.payload.clone())?);
|
2020-04-11 04:36:03 +02:00
|
|
|
Ok(Self { kind, ..self })
|
|
|
|
} else {
|
|
|
|
Ok(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl DynStatus {
|
2020-04-21 22:39:31 +02:00
|
|
|
pub(crate) fn new(payload: &Value) -> Result<Self> {
|
2020-04-11 04:36:03 +02:00
|
|
|
Ok(Self {
|
|
|
|
id: Id::try_from(&payload["account"]["id"])?,
|
|
|
|
username: payload["account"]["acct"]
|
|
|
|
.as_str()
|
2020-04-22 20:38:22 +02:00
|
|
|
.ok_or(err::Event::DynParse)?
|
2020-04-11 04:36:03 +02:00
|
|
|
.to_string(),
|
2020-04-15 02:37:49 +02:00
|
|
|
language: payload["language"].as_str().map(String::from),
|
2020-04-11 04:36:03 +02:00
|
|
|
mentioned_users: HashSet::new(),
|
|
|
|
replied_to_user: Id::try_from(&payload["in_reply_to_account_id"]).ok(),
|
|
|
|
boosted_user: Id::try_from(&payload["reblog"]["account"]["id"]).ok(),
|
|
|
|
})
|
|
|
|
}
|
2020-04-22 20:38:22 +02:00
|
|
|
}
|
2020-04-11 04:36:03 +02:00
|
|
|
|
2020-04-22 20:38:22 +02:00
|
|
|
impl Payload for DynStatus {
|
|
|
|
fn language_unset(&self) -> bool {
|
|
|
|
match &self.language {
|
|
|
|
None => true,
|
|
|
|
Some(empty) if empty == &String::new() => true,
|
|
|
|
Some(_language) => false,
|
2020-04-11 04:36:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-22 20:38:22 +02:00
|
|
|
fn language(&self) -> String {
|
|
|
|
self.language.clone().unwrap_or_default()
|
|
|
|
}
|
|
|
|
/// Returns all users involved in the `Status`.
|
2020-04-11 04:36:03 +02:00
|
|
|
///
|
2020-04-22 20:38:22 +02:00
|
|
|
/// A user is involved in the Status/toot if they:
|
2020-04-11 04:36:03 +02:00
|
|
|
/// * Are mentioned in this toot
|
|
|
|
/// * Wrote this toot
|
|
|
|
/// * Wrote a toot that this toot is replying to (if any)
|
|
|
|
/// * Wrote the toot that this toot is boosting (if any)
|
2020-04-22 20:38:22 +02:00
|
|
|
fn involved_users(&self) -> HashSet<Id> {
|
|
|
|
// involved_users = mentioned_users + author + replied-to user + boosted user
|
2020-04-11 04:36:03 +02:00
|
|
|
let mut involved_users: HashSet<Id> = self.mentioned_users.clone();
|
|
|
|
|
|
|
|
// author
|
|
|
|
involved_users.insert(self.id);
|
|
|
|
// replied-to user
|
|
|
|
if let Some(user_id) = self.replied_to_user {
|
|
|
|
involved_users.insert(user_id);
|
|
|
|
}
|
|
|
|
// boosted user
|
2020-04-22 20:38:22 +02:00
|
|
|
if let Some(boosted_status) = self.boosted_user {
|
|
|
|
involved_users.insert(boosted_status);
|
2020-04-11 04:36:03 +02:00
|
|
|
}
|
2020-04-22 20:38:22 +02:00
|
|
|
involved_users
|
|
|
|
}
|
|
|
|
|
|
|
|
fn author(&self) -> &Id {
|
|
|
|
&self.id
|
|
|
|
}
|
2020-04-11 04:36:03 +02:00
|
|
|
|
2020-04-22 20:38:22 +02:00
|
|
|
fn sent_from(&self) -> &str {
|
|
|
|
let sender_username = &self.username;
|
|
|
|
sender_username.split('@').nth(1).unwrap_or_default() // default occurs when sent from local instance
|
2020-04-11 04:36:03 +02:00
|
|
|
}
|
|
|
|
}
|