tuwunel_core/matrix/event/
redact.rs1use ruma::{
2 OwnedEventId,
3 events::{TimelineEventType, room::redaction::RoomRedactionEventContent},
4 room_version_rules::RoomVersionRules,
5};
6use serde::Deserialize;
7use serde_json::value::to_raw_value;
8
9use super::Event;
10use crate::matrix::pdu::Content;
11
12#[must_use]
26pub(super) fn copy<E: Event>(event: &E) -> (Option<OwnedEventId>, Content) {
27 if *event.event_type() != TimelineEventType::RoomRedaction {
28 return (
29 event.redacts().map(ToOwned::to_owned),
30 Content::from_raw_value(event.content()),
31 );
32 }
33
34 let Ok(mut content) = event.get_content::<RoomRedactionEventContent>() else {
35 return (
36 event.redacts().map(ToOwned::to_owned),
37 Content::from_raw_value(event.content()),
38 );
39 };
40
41 if let Some(redacts) = content.redacts {
42 return (Some(redacts), Content::from_raw_value(event.content()));
43 }
44
45 if let Some(redacts) = event.redacts().map(ToOwned::to_owned) {
46 content.redacts = Some(redacts);
47 return (
48 event.redacts().map(ToOwned::to_owned),
49 Content::from_json(
50 to_raw_value(&content).expect("Must be valid, we only added redacts field"),
51 ),
52 );
53 }
54
55 (event.redacts().map(ToOwned::to_owned), Content::from_raw_value(event.content()))
56}
57
58#[must_use]
59pub(super) fn is_redacted<E: Event>(event: &E) -> bool {
60 let Some(unsigned) = event.unsigned() else {
61 return false;
62 };
63
64 let Ok(unsigned) = ExtractRedactedBecause::deserialize(unsigned) else {
65 return false;
66 };
67
68 unsigned.redacted_because.is_some()
69}
70
71#[must_use]
72pub(super) fn redacts_id<E: Event>(
73 event: &E,
74 room_rules: &RoomVersionRules,
75) -> Option<OwnedEventId> {
76 if *event.kind() != TimelineEventType::RoomRedaction {
77 return None;
78 }
79
80 if room_rules.redaction.content_field_redacts {
81 event
82 .get_content::<RoomRedactionEventContent>()
83 .ok()?
84 .redacts
85 } else {
86 event.redacts().map(ToOwned::to_owned)
87 }
88}
89
90#[derive(Deserialize)]
91struct ExtractRedactedBecause {
92 redacted_because: Option<serde::de::IgnoredAny>,
93}