Files
continuwuity/src/core/pdu/unsigned.rs
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

116 lines
3.1 KiB
Rust
Raw Normal View History

2024-10-25 01:16:01 +00:00
use std::collections::BTreeMap;
use ruma::MilliSecondsSinceUnixEpoch;
use serde::Deserialize;
use serde_json::value::{to_raw_value, RawValue as RawJsonValue, Value as JsonValue};
2024-11-07 03:30:47 +00:00
use super::Pdu;
2024-10-25 01:16:01 +00:00
use crate::{err, implement, is_true, Result};
2024-11-07 03:30:47 +00:00
#[implement(Pdu)]
pub fn remove_transaction_id(&mut self) -> Result {
2024-10-25 01:16:01 +00:00
let Some(unsigned) = &self.unsigned else {
return Ok(());
};
let mut unsigned: BTreeMap<String, Box<RawJsonValue>> = serde_json::from_str(unsigned.get())
.map_err(|e| err!(Database("Invalid unsigned in pdu event: {e}")))?;
2024-10-25 01:16:01 +00:00
unsigned.remove("transaction_id");
self.unsigned = to_raw_value(&unsigned)
.map(Some)
.expect("unsigned is valid");
Ok(())
}
2024-11-07 03:30:47 +00:00
#[implement(Pdu)]
pub fn add_age(&mut self) -> Result {
2024-10-25 01:16:01 +00:00
let mut unsigned: BTreeMap<String, Box<RawJsonValue>> = self
.unsigned
.as_ref()
.map_or_else(|| Ok(BTreeMap::new()), |u| serde_json::from_str(u.get()))
.map_err(|e| err!(Database("Invalid unsigned in pdu event: {e}")))?;
// deliberately allowing for the possibility of negative age
let now: i128 = MilliSecondsSinceUnixEpoch::now().get().into();
let then: i128 = self.origin_server_ts.into();
let this_age = now.saturating_sub(then);
unsigned.insert("age".to_owned(), to_raw_value(&this_age).expect("age is valid"));
self.unsigned = to_raw_value(&unsigned)
.map(Some)
.expect("unsigned is valid");
Ok(())
}
2024-11-07 03:30:47 +00:00
#[implement(Pdu)]
2025-02-06 09:53:53 +00:00
pub fn add_relation(&mut self, name: &str, pdu: Option<&Pdu>) -> Result {
use serde_json::Map;
let mut unsigned: Map<String, JsonValue> = self
2024-11-07 03:30:47 +00:00
.unsigned
.as_ref()
2025-02-06 09:53:53 +00:00
.map_or_else(|| Ok(Map::new()), |u| serde_json::from_str(u.get()))
2024-11-07 03:30:47 +00:00
.map_err(|e| err!(Database("Invalid unsigned in pdu event: {e}")))?;
2025-02-06 09:53:53 +00:00
let pdu = pdu
.map(serde_json::to_value)
.transpose()?
.unwrap_or_else(|| JsonValue::Object(Map::new()));
2024-11-07 03:30:47 +00:00
2025-02-06 09:53:53 +00:00
unsigned
.entry("m.relations")
.or_insert(JsonValue::Object(Map::new()))
2024-11-07 03:30:47 +00:00
.as_object_mut()
2025-02-06 09:53:53 +00:00
.unwrap()
.insert(name.to_owned(), pdu);
2024-11-07 03:30:47 +00:00
self.unsigned = to_raw_value(&unsigned)
.map(Some)
.expect("unsigned is valid");
Ok(())
}
#[implement(Pdu)]
2024-10-25 01:16:01 +00:00
pub fn contains_unsigned_property<F>(&self, property: &str, is_type: F) -> bool
where
F: FnOnce(&JsonValue) -> bool,
{
self.get_unsigned_as_value()
.get(property)
.map(is_type)
.is_some_and(is_true!())
}
2024-11-07 03:30:47 +00:00
#[implement(Pdu)]
2024-10-25 01:16:01 +00:00
pub fn get_unsigned_property<T>(&self, property: &str) -> Result<T>
where
T: for<'de> Deserialize<'de>,
{
self.get_unsigned_as_value()
.get_mut(property)
.map(JsonValue::take)
.map(serde_json::from_value)
.ok_or(err!(Request(NotFound("property not found in unsigned object"))))?
.map_err(|e| err!(Database("Failed to deserialize unsigned.{property} into type: {e}")))
}
2024-11-07 03:30:47 +00:00
#[implement(Pdu)]
2024-10-25 01:16:01 +00:00
#[must_use]
pub fn get_unsigned_as_value(&self) -> JsonValue {
self.get_unsigned::<JsonValue>().unwrap_or_default()
}
2024-10-25 01:16:01 +00:00
2024-11-07 03:30:47 +00:00
#[implement(Pdu)]
2024-10-25 01:16:01 +00:00
pub fn get_unsigned<T>(&self) -> Result<JsonValue> {
self.unsigned
.as_ref()
.map(|raw| raw.get())
.map(serde_json::from_str)
.ok_or(err!(Request(NotFound("\"unsigned\" property not found in pdu"))))?
.map_err(|e| err!(Database("Failed to deserialize \"unsigned\" into value: {e}")))
}