From 7e6c90ecb9123b73f7108adc4945cd76dd4abb0e Mon Sep 17 00:00:00 2001 From: Devin R Date: Tue, 7 Apr 2020 17:34:21 -0400 Subject: [PATCH] design doc to help me define the layers? --- design.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 design.md diff --git a/design.md b/design.md new file mode 100644 index 00000000..f5cde97a --- /dev/null +++ b/design.md @@ -0,0 +1,97 @@ +# Matrix Rust SDK + +## Design and Layout + +#### Async Client +The highest level structure that ties the other pieces of functionality together. The client is responsible for the Request/Response cycle. It knows how to + - login + - send messages + - encryption ... + - sync client state with the server + - make raw Http requests + +#### Base Client +In addition to Http the `AsyncClient` passes along methods from the `BaseClient` that deal with `Room`s and `RoomMember`s. This allows the client to keep track of more complicated information that needs to be calculated in some way. + - human readable room names + - power level? + - ignored list? + - push rulesset? + - more? + +#### Crypto State Machine + + +#### Client State/Room and RoomMember +The `BaseClient` is responsible for keeping state in sync through the `IncomingResponse`s of `AsyncClient` or querying the `StateStore`. By processing and then delegating incoming `RoomEvent`s, `StateEvent`s, `PresenceEvent`, `IncomingAccountData` and `EphemeralEvent`s to the correct `Room` in the base clients `HashMap` or further to `Room`'s `RoomMember` via the members `HashMap`. The `BaseClient` is also responsible for emitting the incoming events to the `EventEmitter` trait. + +```rust +/// A Matrix room. +pub struct Room { + /// The unique id of the room. + pub room_id: RoomId, + /// The name of the room, clients use this to represent a room. + pub room_name: RoomName, + /// The mxid of our own user. + pub own_user_id: UserId, + /// The mxid of the room creator. + pub creator: Option, + /// The map of room members. + pub members: HashMap, + /// A list of users that are currently typing. + pub typing_users: Vec, + /// The power level requirements for specific actions in this room + pub power_levels: Option, + // TODO when encryption events are handled we store algorithm used and rotation time. + /// A flag indicating if the room is encrypted. + pub encrypted: bool, + /// Number of unread notifications with highlight flag set. + pub unread_highlight: Option, + /// Number of unread notifications. + pub unread_notifications: Option, +} +``` + +```rust +pub struct RoomMember { + /// The unique mxid of the user. + pub user_id: UserId, + /// The human readable name of the user. + pub display_name: Option, + /// The matrix url of the users avatar. + pub avatar_url: Option, + /// The time, in ms, since the user interacted with the server. + pub last_active_ago: Option, + /// If the user should be considered active. + pub currently_active: Option, + /// The unique id of the room. + pub room_id: Option, + /// If the member is typing. + pub typing: Option, + /// The presence of the user, if found. + pub presence: Option, + /// The presence status message, if found. + pub status_msg: Option, + /// The users power level. + pub power_level: Option, + /// The normalized power level of this `RoomMember` (0-100). + pub power_level_norm: Option, + /// The `MembershipState` of this `RoomMember`. + pub membership: MembershipState, + /// The human readable name of this room member. + pub name: String, + /// The events that created the state of this room member. + pub events: Vec, + /// The `PresenceEvent`s connected to this user. + pub presence_events: Vec, +} +``` + +#### State Store +The `BaseClient` also has access to a `dyn StateStore` this is an abstraction around a "database" to keep client state without requesting a full sync from the server on start up. A default implementation that serializes/deserializes json to files in a specified directory can be used. The user can also implement `StateStore` to fit any storage solution they choose. + - load + - store/save + - update ?? + +#### Event Emitter +The consumer of this crate can implement the `EventEmitter` trait for full control over how incoming events are handled by their client. If that isn't enough it is possible to receive every incoming response with the `AsyncClient::sync_forever` callback. + - list the methods for `EventEmitter`?