1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
//! Types for the *m.room.create* event.

use std::convert::TryFrom;

use ruma_events_macros::ruma_event;
use ruma_identifiers::{EventId, RoomId, RoomVersionId, UserId};
use serde::{Deserialize, Serialize};

ruma_event! {
    /// This is the first event in a room and cannot be changed. It acts as the root of all other
    /// events.
    CreateEvent {
        kind: StateEvent,
        event_type: "m.room.create",
        content: {
            /// The `user_id` of the room creator. This is set by the homeserver.
            pub creator: UserId,

            /// Whether or not this room's data should be transferred to other homeservers.
            #[serde(rename = "m.federate", default = "ruma_serde::default_true")]
            pub federate: bool,

            /// The version of the room. Defaults to "1" if the key does not exist.
            #[serde(default = "default_room_version_id")]
            pub room_version: RoomVersionId,

            /// A reference to the room this room replaces, if the previous room was upgraded.
            #[serde(skip_serializing_if = "Option::is_none")]
            pub predecessor: Option<PreviousRoom>,
        },
    }
}

/// A reference to an old room replaced during a room version upgrade.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct PreviousRoom {
    /// The ID of the old room.
    pub room_id: RoomId,

    /// The event ID of the last known event in the old room.
    pub event_id: EventId,
}

/// Used to default the `room_version` field to room version 1.
fn default_room_version_id() -> RoomVersionId {
    RoomVersionId::try_from("1").unwrap()
}

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use matches::assert_matches;
    use ruma_identifiers::{RoomVersionId, UserId};
    use serde_json::{from_value as from_json_value, json, to_value as to_json_value};

    use super::CreateEventContent;
    use crate::EventJson;

    #[test]
    fn serialization() {
        let content = CreateEventContent {
            creator: UserId::try_from("@carl:example.com").unwrap(),
            federate: true,
            room_version: RoomVersionId::version_4(),
            predecessor: None,
        };

        let json = json!({
            "creator": "@carl:example.com",
            "m.federate": true,
            "room_version": "4"
        });

        assert_eq!(to_json_value(&content).unwrap(), json);
    }

    #[test]
    fn deserialization() {
        let json = json!({
            "creator": "@carl:example.com",
            "m.federate": true,
            "room_version": "4"
        });

        assert_matches!(
            from_json_value::<EventJson<CreateEventContent>>(json)
                .unwrap()
                .deserialize()
                .unwrap(),
            CreateEventContent {
                creator,
                federate: true,
                room_version,
                predecessor: None,
            } if creator == "@carl:example.com"
                && room_version == RoomVersionId::version_4()
        );
    }
}