tuwunel_core/matrix/event/
id.rs1use ruma::{CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, RoomVersionId};
2use serde_json::value::RawValue as RawJsonValue;
3
4use crate::{Result, debug_error, err, matrix::room_version};
5
6#[tracing::instrument(
11 name = "gen_event_id",
12 level = "debug",
13 skip_all,
14 fields(
15 len = pdu.get().len(),
16 )
17)]
18pub fn gen_event_id_canonical_json(
19 pdu: &RawJsonValue,
20 room_version_id: &RoomVersionId,
21) -> Result<(OwnedEventId, CanonicalJsonObject)> {
22 let value: CanonicalJsonObject = serde_json::from_str(pdu.get())
23 .map_err(|e| err!(BadServerResponse(warn!("Error parsing canonical event: {e}"))))
24 .inspect_err(|e| debug_error!("{pdu:#?} {e:?}"))?;
25
26 let event_id = gen_event_id(&value, room_version_id)?;
27
28 Ok((event_id, value))
29}
30
31#[tracing::instrument(
35 level = "debug",
36 skip_all,
37 fields(
38 members = value.len(),
39 room_version = ?room_version_id,
40 )
41)]
42pub fn gen_event_id(
43 value: &CanonicalJsonObject,
44 room_version_id: &RoomVersionId,
45) -> Result<OwnedEventId> {
46 let room_version_rules = room_version::rules(room_version_id)?;
47 let require_event_id = room_version_rules.event_format.require_event_id;
48
49 if let Some(event_id) = require_event_id
52 .then(|| value.get("event_id"))
53 .flatten()
54 .and_then(CanonicalJsonValue::as_str)
55 .map(OwnedEventId::try_from)
56 .transpose()?
57 {
58 return Ok(event_id);
59 }
60
61 let server_name = require_event_id
64 .then(|| value.get("origin"))
65 .flatten()
66 .and_then(CanonicalJsonValue::as_str);
67
68 let reference_hash = ruma::signatures::reference_hash(value, &room_version_rules)?;
69
70 OwnedEventId::from_parts('$', &reference_hash, server_name).map_err(Into::into)
71}