From e55a63629cda9e6f4d5cae25c39eb7552b1db017 Mon Sep 17 00:00:00 2001
From: timokoesters <timo@koesters.xyz>
Date: Mon, 6 Apr 2020 14:33:02 +0200
Subject: [PATCH] feat: state event support

---
 src/data.rs |  9 +++----
 src/main.rs | 73 +++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 63 insertions(+), 19 deletions(-)

diff --git a/src/data.rs b/src/data.rs
index 0467d22d..56878d7d 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -1,9 +1,5 @@
 use crate::{utils, Database, PduEvent};
-use log::debug;
-use ruma_events::{
-    room::message::{MessageEvent, MessageEventContent},
-    EventType,
-};
+use ruma_events::EventType;
 use ruma_federation_api::RoomV3Pdu;
 use ruma_identifiers::{EventId, RoomId, UserId};
 use std::{
@@ -181,6 +177,7 @@ impl Data {
         sender: UserId,
         event_type: EventType,
         content: serde_json::Value,
+        state_key: Option<String>,
     ) -> EventId {
         // prev_events are the leaves of the current graph. This method removes all leaves from the
         // room and replaces them with our event
@@ -208,7 +205,7 @@ impl Data {
             origin_server_ts: utils::millis_since_unix_epoch(),
             kind: event_type,
             content,
-            state_key: None,
+            state_key,
             prev_events,
             depth: depth.try_into().unwrap(),
             auth_events: Vec::new(),
diff --git a/src/main.rs b/src/main.rs
index a5049306..72f3ce7c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,27 +9,27 @@ pub use data::Data;
 pub use database::Database;
 pub use pdu::PduEvent;
 
-use log::{debug, error};
+use log::debug;
 use rocket::{get, options, post, put, routes, State};
 use ruma_client_api::{
     error::{Error, ErrorKind},
     r0::{
-        account::register, alias::get_alias, membership::join_room_by_id,
-        message::create_message_event, room::create_room, session::login, sync::sync_events,
+        account::register,
+        alias::get_alias,
+        membership::join_room_by_id,
+        message::create_message_event,
+        room::create_room,
+        session::login,
+        state::{create_state_event_for_empty_key, create_state_event_for_key},
+        sync::sync_events,
     },
     unversioned::get_supported_versions,
 };
-use ruma_events::{
-    collections::all::RoomEvent, room::message::MessageEvent, EventResult, EventType,
-};
-use ruma_identifiers::{EventId, RoomId, UserId};
+use ruma_events::EventType;
+use ruma_identifiers::{RoomId, UserId};
 use ruma_wrapper::{MatrixResult, Ruma};
-use serde_json::{json, map::Map};
-use std::{
-    collections::HashMap,
-    convert::{TryFrom, TryInto},
-    path::PathBuf,
-};
+use serde_json::json;
+use std::{collections::HashMap, convert::TryInto, path::PathBuf};
 
 #[get("/_matrix/client/versions")]
 fn get_supported_versions_route() -> MatrixResult<get_supported_versions::Response> {
@@ -188,6 +188,7 @@ fn create_room_route(
         body.user_id.clone().expect("user is authenticated"),
         EventType::RoomMessage,
         json!({"msgtype": "m.text", "body": "Hello"}),
+        None,
     );
 
     MatrixResult(Ok(create_room::Response { room_id }))
@@ -247,10 +248,54 @@ fn create_message_event_route(
         body.user_id.clone().expect("user is authenticated"),
         body.event_type.clone(),
         body.json_body,
+        None,
     );
     MatrixResult(Ok(create_message_event::Response { event_id }))
 }
 
+#[put(
+    "/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>/<_state_key>",
+    data = "<body>"
+)]
+fn create_state_event_for_key_route(
+    data: State<Data>,
+    _room_id: String,
+    _event_type: String,
+    _state_key: String,
+    body: Ruma<create_state_event_for_key::Request>,
+) -> MatrixResult<create_state_event_for_key::Response> {
+    // Reponse of with/without key is the same
+    let event_id = data.pdu_append(
+        body.room_id.clone(),
+        body.user_id.clone().expect("user is authenticated"),
+        body.event_type.clone(),
+        body.json_body.clone(),
+        Some(body.state_key.clone()),
+    );
+    MatrixResult(Ok(create_state_event_for_key::Response { event_id }))
+}
+
+#[put(
+    "/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>",
+    data = "<body>"
+)]
+fn create_state_event_for_empty_key_route(
+    data: State<Data>,
+    _room_id: String,
+    _event_type: String,
+    body: Ruma<create_state_event_for_empty_key::Request>,
+) -> MatrixResult<create_state_event_for_empty_key::Response> {
+    // Reponse of with/without key is the same
+    let event_id = data.pdu_append(
+        body.room_id.clone(),
+        body.user_id.clone().expect("user is authenticated"),
+        body.event_type.clone(),
+        body.json_body,
+        Some("".to_owned()),
+    );
+    MatrixResult(Ok(create_state_event_for_empty_key::Response { event_id }))
+}
+
 #[get("/_matrix/client/r0/sync", data = "<body>")]
 fn sync_route(
     data: State<Data>,
@@ -333,6 +378,8 @@ fn main() {
                 get_alias_route,
                 join_room_by_id_route,
                 create_message_event_route,
+                create_state_event_for_key_route,
+                create_state_event_for_empty_key_route,
                 sync_route,
                 options_route,
             ],