arminius_lib_events/
conversions.rs1use ruma::{CanonicalJsonObject, CanonicalJsonValue};
17use serde_json::value::RawValue as RawJsonValue;
18
19use crate::{
20 errors::SigningError,
21 types::{ClientContext, HashedEventRef},
22};
23
24pub fn build_unsigned(ctx: ClientContext) -> Option<serde_json::Value> {
26 let mut unsigned = serde_json::Map::new();
27 if let Some(age) = ctx.age {
28 unsigned.insert("age".to_owned(), serde_json::Value::Number(age.into()));
29 }
30 if let Some(transaction_id) = ctx.transaction_id {
31 unsigned.insert(
32 "transaction_id".to_owned(),
33 serde_json::Value::String(transaction_id.to_string()),
34 );
35 }
36 if let Some(prev_content) = ctx.prev_content {
37 unsigned.insert("prev_content".to_owned(), prev_content);
38 }
39
40 (!unsigned.is_empty()).then_some(serde_json::Value::Object(unsigned))
41}
42
43pub fn serialize_hashed_event_ref(event: &HashedEventRef) -> serde_json::Value {
45 let hashes = event.hashes.to_json_value();
46 serde_json::Value::Array(vec![serde_json::Value::String(event.event_id.to_string()), hashes])
47}
48
49pub fn extract_signatures(
51 object: &CanonicalJsonObject,
52) -> Result<ruma::ServerSignatures, SigningError> {
53 let signatures = object.get("signatures").ok_or_else(|| {
54 SigningError::SignatureCreation("Missing signatures in canonical event".to_owned())
55 })?;
56
57 let CanonicalJsonValue::Object(servers) = signatures else {
58 return Err(SigningError::SignatureCreation("signatures must be a JSON object".to_owned()));
59 };
60
61 let mut parsed = ruma::ServerSignatures::new();
62 for (server, keys) in servers {
63 let server_name = ruma::ServerName::parse(server).map_err(|err| {
64 SigningError::InvalidContent(format!("Error parsing server name: {err}"))
65 })?;
66 let CanonicalJsonValue::Object(keys) = keys else {
67 return Err(SigningError::SignatureCreation(
68 "signatures must map servers to key sets".to_owned(),
69 ));
70 };
71
72 for (key_id, signature) in keys {
73 let CanonicalJsonValue::String(signature) = signature else {
74 return Err(SigningError::SignatureCreation(
75 "signature values must be strings".to_owned(),
76 ));
77 };
78 parsed.insert_signature(
79 server_name.clone(),
80 key_id.parse().map_err(|err| {
81 SigningError::InvalidContent(format!("Error parsing key id: {err}"))
82 })?,
83 signature.to_owned(),
84 );
85 }
86 }
87
88 Ok(parsed)
89}
90
91pub fn raw_json(value: &serde_json::Value) -> Box<RawJsonValue> {
93 let serialized = value.to_string();
94 #[expect(
95 clippy::expect_used,
96 reason = "RawValue::from_string can fail if the input is not valid JSON. But we know it's valid JSON, we just serialized it"
97 )]
98 RawJsonValue::from_string(serialized)
99 .expect("RawValue::from_string can fail if the input is not valid JSON. But we know it's valid JSON, we just serialized it")
100}
101
102mod tests;