Marshal and Unmarshal methods for roomserver input api (#16)

* Marshal and Unmarshal methods for roomserver input api

* Comments for why we don't json.marshal the InputRoomEvent directly

* More comments

* s/m.room.create/the first event/
This commit is contained in:
Mark Haines 2017-02-22 16:05:18 +00:00 committed by GitHub
parent 094345830e
commit c96d3eec0c
2 changed files with 65 additions and 2 deletions

View File

@ -1,6 +1,10 @@
// Package api provides the types that are used to communicate with the roomserver.
package api
import (
"encoding/json"
)
const (
// KindOutlier event fall outside the contiguous event graph.
// We do not have the state for these events.
@ -36,7 +40,61 @@ type InputRoomEvent struct {
// For example many matrix events forget to reference the m.room.create event even though it is needed for auth.
// (since synapse allows this to happen we have to allow it as well.)
AuthEventIDs []string
// Whether the state is supplied as a list of event IDs or whether it
// should be derived from the state at the previous events.
HasState bool
// Optional list of state event IDs forming the state before this event.
// These state events must have already been persisted.
// These are only used if HasState is true.
// The list can be empty, for example when storing the first event in a room.
StateEventIDs []string
}
// UnmarshalJSON implements json.Unmarshaller
func (ire *InputRoomEvent) UnmarshalJSON(data []byte) error {
// Create a struct rather than unmarshalling directly into the InputRoomEvent
// so that we can use json.RawMessage.
// We use json.RawMessage so that the event JSON is sent as JSON rather than
// being base64 encoded which is the default for []byte.
var content struct {
Kind int
Event *json.RawMessage
AuthEventIDs []string
StateEventIDs []string
HasState bool
}
if err := json.Unmarshal(data, &content); err != nil {
return err
}
ire.Kind = content.Kind
ire.AuthEventIDs = content.AuthEventIDs
ire.StateEventIDs = content.StateEventIDs
ire.HasState = content.HasState
if content.Event != nil {
ire.Event = []byte(*content.Event)
}
return nil
}
// MarshalJSON implements json.Marshaller
func (ire InputRoomEvent) MarshalJSON() ([]byte, error) {
// Create a struct rather than marshalling directly from the InputRoomEvent
// so that we can use json.RawMessage.
// We use json.RawMessage so that the event JSON is sent as JSON rather than
// being base64 encoded which is the default for []byte.
event := json.RawMessage(ire.Event)
content := struct {
Kind int
Event *json.RawMessage
AuthEventIDs []string
StateEventIDs []string
HasState bool
}{
Kind: ire.Kind,
AuthEventIDs: ire.AuthEventIDs,
StateEventIDs: ire.StateEventIDs,
Event: &event,
HasState: ire.HasState,
}
return json.Marshal(&content)
}

View File

@ -69,7 +69,7 @@ func processRoomEvent(db RoomEventDatabase, input api.InputRoomEvent) error {
if stateAtEvent.BeforeStateSnapshotNID == 0 {
// We haven't calculated a state for this event yet.
// Lets calculate one.
if input.StateEventIDs != nil {
if input.HasState {
// We've been told what the state at the event is so we don't need to calculate it.
// Check that those state events are in the database and store the state.
entries, err := db.StateEntriesForEventIDs(input.StateEventIDs)
@ -89,6 +89,11 @@ func processRoomEvent(db RoomEventDatabase, input api.InputRoomEvent) error {
db.SetState(stateAtEvent.EventNID, stateAtEvent.BeforeStateSnapshotNID)
}
if input.Kind == api.KindBackfill {
// Backfill is not implemented.
panic("Not implemented")
}
// Update the extremities of the event graph for the room
if err := updateLatestEvents(db, roomNID, stateAtEvent, event); err != nil {
return err
@ -102,5 +107,5 @@ func processRoomEvent(db RoomEventDatabase, input api.InputRoomEvent) error {
// - The event itself
// - The visiblity of the event, i.e. who is allowed to see the event.
// - The changes to the current state of the room.
panic("Not implemented")
return nil
}