Skip to content

Commit 7a1dbf4

Browse files
committed
Add MatrixStateEvent Types
1 parent cdc66db commit 7a1dbf4

14 files changed

+599
-408
lines changed

Sources/MatrixClient/API/Events/Room/RoomMessageEvent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public struct MatrixMessageEvent: MatrixEvent {
77
@MatrixCodableMessageType
88
public var content: MatrixMessageType
99
public var eventID: String?
10-
public var sender: String?
10+
public var sender: MatrixFullUserIdentifier?
1111
public var date: Date?
1212
public var unsigned: AnyCodable?
1313

Sources/MatrixClient/API/Events/Room/RoomReactionEvent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public struct MatrixReactionEvent: MatrixEvent {
66

77
public var content: Content
88
public var eventID: String?
9-
public var sender: String?
9+
public var sender: MatrixFullUserIdentifier?
1010
public var date: Date?
1111
public var unsigned: AnyCodable?
1212

Sources/MatrixClient/API/Events/Room/RoomRedactionEvent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public struct MatrixRedactionEvent: MatrixEvent {
66

77
public var content: Content
88
public var eventID: String?
9-
public var sender: String?
9+
public var sender: MatrixFullUserIdentifier?
1010
public var date: Date?
1111
public var unsigned: AnyCodable?
1212

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//
2+
// File.swift
3+
//
4+
//
5+
// Created by Finn Behrens on 24.04.22.
6+
//
7+
8+
import AnyCodable
9+
import Foundation
10+
11+
public struct MatrixStateEvent: MatrixEvent {
12+
public static let type: String = ""
13+
14+
/// The content of the event.
15+
@MatrixCodableStateEventType
16+
var content: MatrixStateEventType
17+
18+
public var stateKey: String = ""
19+
20+
public var eventID: String?
21+
22+
public var sender: MatrixFullUserIdentifier?
23+
24+
public var date: Date?
25+
26+
public var unsigned: AnyCodable?
27+
28+
enum CodingKeys: String, CodingKey {
29+
case content
30+
case stateKey = "state_key"
31+
case eventID = "event_id"
32+
case sender
33+
case date = "origin_server_ts"
34+
case unsigned
35+
}
36+
37+
public init(from decoder: Decoder) throws {
38+
let container = try decoder.container(keyedBy: CodingKeys.self)
39+
stateKey = try container.decode(String.self, forKey: .stateKey)
40+
eventID = try container.decode(String.self, forKey: .eventID)
41+
sender = try container.decode(MatrixFullUserIdentifier.self, forKey: .sender)
42+
date = try container.decodeIfPresent(Date.self, forKey: .date)
43+
unsigned = try container.decodeIfPresent(AnyCodable.self, forKey: .unsigned)
44+
45+
let typeContainer = try decoder.container(keyedBy: MatrixStateEventTypeCodingKeys.self)
46+
let typeId = try typeContainer.decode(String.self, forKey: .type)
47+
48+
let superEncoder = try container.superDecoder(forKey: .content)
49+
_content = try MatrixCodableStateEventType(from: superEncoder, typeID: typeId)
50+
}
51+
52+
public func encode(to encoder: Encoder) throws {
53+
var container = encoder.container(keyedBy: CodingKeys.self)
54+
try container.encode(stateKey, forKey: .stateKey)
55+
try container.encode(eventID, forKey: .eventID)
56+
try container.encode(sender, forKey: .sender)
57+
try container.encodeIfPresent(date, forKey: .date)
58+
try container.encodeIfPresent(unsigned, forKey: .unsigned)
59+
60+
let contentType = Swift.type(of: content)
61+
62+
var typeContainer = encoder.container(keyedBy: MatrixStateEventTypeCodingKeys.self)
63+
try typeContainer.encode(contentType.type, forKey: .type)
64+
65+
let superEncoder = container.superEncoder(forKey: .content)
66+
try _content.encode(to: superEncoder)
67+
}
68+
}

Sources/MatrixClient/API/Events/RoomEvent.swift

Lines changed: 76 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ public protocol MatrixEvent: Codable {
88
static var type: String { get }
99

1010
var eventID: String? { get }
11-
var sender: String? { get }
11+
var sender: MatrixFullUserIdentifier? { get }
1212
var date: Date? { get }
1313
var unsigned: AnyCodable? { get }
1414
}
1515

1616
/// The coding keys needed to determine an event's type before decoding.
17-
enum MatrixEventTypeKeys: CodingKey {
17+
enum MatrixEventTypeKeys: String, CodingKey {
1818
case type
19+
case stateKey = "state_key"
1920
}
2021

2122
enum MatrixEventCodableError: Error {
@@ -38,6 +39,29 @@ extension CodingUserInfoKey {
3839
}
3940
}
4041

42+
public struct MatrixInvalidEvent: MatrixEvent {
43+
public static let type: String = ""
44+
45+
public var type: String?
46+
47+
public var eventID: String?
48+
49+
public var sender: MatrixFullUserIdentifier?
50+
51+
public var date: Date? {
52+
nil
53+
}
54+
55+
public var unsigned: AnyCodable? {
56+
nil
57+
}
58+
59+
enum CodingKeys: String, CodingKey {
60+
case eventID = "event_id"
61+
case sender
62+
}
63+
}
64+
4165
// TODO: encodable
4266
@propertyWrapper
4367
public struct MatrixCodableEvents<Value: Collection>: Codable where Value.Element == MatrixEvent {
@@ -51,28 +75,51 @@ public struct MatrixCodableEvents<Value: Collection>: Codable where Value.Elemen
5175
// these can throw as something has gone seriously wrong if the type key is missing
5276
let container = try decoder.container(keyedBy: MatrixEventTypeKeys.self)
5377
let typeID = try container.decode(String.self, forKey: .type)
54-
55-
guard let types = decoder.userInfo[.matrixEventTypes] as? [MatrixEvent.Type] else {
56-
// the decoder must be supplied with some event types to decode
57-
throw MatrixEventCodableError.missingTypes
58-
}
59-
60-
guard let matchingType = types.first(where: { $0.type == typeID }) else {
61-
// simply ignore events with no matching type as throwing would prevent access to other events
78+
let stateKey = try container.decodeIfPresent(String.self, forKey: .stateKey)
79+
80+
do {
81+
if stateKey != nil {
82+
let stateEvent = try MatrixStateEvent(from: decoder)
83+
guard let decoded = stateEvent as? T
84+
else {
85+
throw MatrixEventCodableError.unableToCast(decoded: stateEvent, into: "state_event")
86+
}
87+
wrappedEvent = decoded
88+
return
89+
}
90+
91+
guard let types = decoder.userInfo[.matrixEventTypes] as? [MatrixEvent.Type] else {
92+
// the decoder must be supplied with some event types to decode
93+
throw MatrixEventCodableError.missingTypes
94+
}
95+
96+
guard let matchingType = types.first(where: { $0.type == typeID }) else {
97+
// simply ignore events with no matching type as throwing would prevent access to other events
98+
return
99+
}
100+
101+
guard let decoded = try? matchingType.init(from: decoder) else {
102+
assertionFailure("Failed to decode MatrixEvent as \(String(describing: T.self))")
103+
return
104+
}
105+
106+
guard let decoded = decoded as? T else {
107+
// something has probably gone very wrong at this stage
108+
throw MatrixEventCodableError.unableToCast(decoded: decoded, into: String(describing: T.self))
109+
}
110+
wrappedEvent = decoded
62111
return
63-
}
112+
} catch {
113+
print(error.localizedDescription)
114+
var event = try! MatrixInvalidEvent(from: decoder)
115+
event.type = typeID
64116

65-
guard let decoded = try? matchingType.init(from: decoder) else {
66-
assertionFailure("Failed to decode MatrixEvent as \(String(describing: T.self))")
67-
return
68-
}
117+
guard let decoded = event as? T else {
118+
throw MatrixEventCodableError.missingTypes
119+
}
69120

70-
guard let decoded = decoded as? T else {
71-
// something has probably gone very wrong at this stage
72-
throw MatrixEventCodableError.unableToCast(decoded: decoded, into: String(describing: T.self))
121+
wrappedEvent = decoded
73122
}
74-
75-
wrappedEvent = decoded
76123
}
77124

78125
func encode(to encoder: Encoder) throws {
@@ -97,11 +144,15 @@ public struct MatrixCodableEvents<Value: Collection>: Codable where Value.Elemen
97144
}
98145

99146
public init(from decoder: Decoder) {
100-
guard let container = try? decoder.singleValueContainer(),
101-
let wrappers = try? container.decode([EventWrapper<Value.Element>].self)
102-
else { return }
103-
104-
wrappedValue = wrappers.compactMap(\.wrappedEvent) as? Value
147+
do {
148+
let container = try decoder.singleValueContainer()
149+
let wrappers = try container.decode([EventWrapper<Value.Element>].self)
150+
wrappedValue = wrappers.compactMap(\.wrappedEvent) as? Value
151+
} catch {
152+
if #available(iOS 14.0, *) {
153+
MatrixClient.logger.warning("Failed to parse sync: \(error.localizedDescription)")
154+
} else {}
155+
}
105156
}
106157

107158
public func encode(to encoder: Encoder) throws {

Sources/MatrixClient/API/Events/State/RoomCreateEvent.swift

Lines changed: 0 additions & 91 deletions
This file was deleted.

Sources/MatrixClient/API/Events/State/RoomEncryptionEvent.swift

Lines changed: 0 additions & 25 deletions
This file was deleted.

Sources/MatrixClient/API/Events/State/RoomMemberEvent.swift

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)