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