2024-06-19 15:06:39 +00:00
|
|
|
import Foundation
|
|
|
|
|
2024-12-16 08:04:14 +00:00
|
|
|
enum StanzaType: Codable & Equatable {
|
|
|
|
enum IqType: String, Codable & Equatable {
|
2024-06-19 15:06:39 +00:00
|
|
|
case get
|
|
|
|
case set
|
|
|
|
case result
|
|
|
|
case error
|
|
|
|
}
|
|
|
|
|
2024-12-16 08:04:14 +00:00
|
|
|
enum MessageType: String, Codable & Equatable {
|
2024-06-19 15:06:39 +00:00
|
|
|
case chat
|
|
|
|
case groupchat
|
|
|
|
case headline
|
|
|
|
case normal
|
|
|
|
case error
|
|
|
|
case none
|
|
|
|
}
|
|
|
|
|
2024-12-16 08:04:14 +00:00
|
|
|
enum PresenceType: String, Codable & Equatable {
|
2024-06-19 15:06:39 +00:00
|
|
|
case subscribe
|
|
|
|
case unsubscribe
|
|
|
|
case subscribed
|
|
|
|
case unsubscribed
|
|
|
|
}
|
|
|
|
|
|
|
|
case iq(IqType)
|
|
|
|
case message(MessageType)
|
|
|
|
case presense(PresenceType)
|
|
|
|
|
|
|
|
// Should never appear
|
|
|
|
case unknown
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Stanza {
|
|
|
|
let wrapped: XMLElement
|
|
|
|
|
|
|
|
init?(wrap: XMLElement) {
|
|
|
|
guard ["iq", "message", "presence"].contains(wrap.name) else { return nil }
|
|
|
|
wrapped = wrap
|
|
|
|
}
|
|
|
|
|
|
|
|
var type: StanzaType {
|
|
|
|
switch wrapped.name {
|
|
|
|
case "iq":
|
|
|
|
if let type = StanzaType.IqType(rawValue: wrapped.attributes["type"] ?? "") {
|
|
|
|
return .iq(type)
|
|
|
|
} else {
|
|
|
|
warn()
|
|
|
|
return .unknown
|
|
|
|
}
|
|
|
|
|
|
|
|
case "message":
|
|
|
|
let type = StanzaType.MessageType(rawValue: wrapped.attributes["type"] ?? "none") ?? .none
|
|
|
|
return .message(type)
|
|
|
|
|
|
|
|
case "presence":
|
|
|
|
if let type = StanzaType.PresenceType(rawValue: wrapped.attributes["type"] ?? "") {
|
|
|
|
return .presense(type)
|
|
|
|
} else {
|
|
|
|
warn()
|
|
|
|
return .unknown
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
warn()
|
|
|
|
return .unknown
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var id: String? {
|
|
|
|
wrapped.attributes["id"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-16 13:11:46 +00:00
|
|
|
// MARK: Init IQ Stanza
|
2024-06-19 15:06:39 +00:00
|
|
|
extension Stanza {
|
2024-12-16 13:11:46 +00:00
|
|
|
static func iqGet(payload: XMLElement) -> Stanza? {
|
|
|
|
buildIq(direction: "get", from: nil, to: nil, payload: payload)
|
2024-06-19 15:06:39 +00:00
|
|
|
}
|
|
|
|
|
2024-12-16 13:11:46 +00:00
|
|
|
static func iqGet(from: String, payload: XMLElement) -> Stanza? {
|
|
|
|
buildIq(direction: "get", from: from, to: nil, payload: payload)
|
|
|
|
}
|
|
|
|
|
|
|
|
static func iqSet(payload: XMLElement) -> Stanza? {
|
|
|
|
buildIq(direction: "set", from: nil, to: nil, payload: payload)
|
|
|
|
}
|
|
|
|
|
|
|
|
static func iqSet(from: String, payload: XMLElement) -> Stanza? {
|
|
|
|
buildIq(direction: "set", from: from, to: nil, payload: payload)
|
|
|
|
}
|
|
|
|
|
|
|
|
// build iq stanza
|
|
|
|
private static func buildIq(direction: String, from: String?, to: String?, payload: XMLElement) -> Stanza? {
|
|
|
|
var attributes = ["id": XMLElement.randomId, "type": direction]
|
|
|
|
if let from {
|
|
|
|
attributes["from"] = from
|
|
|
|
}
|
|
|
|
if let to {
|
|
|
|
attributes["to"] = to
|
2024-12-16 12:51:12 +00:00
|
|
|
}
|
2024-06-19 15:06:39 +00:00
|
|
|
let req = XMLElement(
|
|
|
|
name: "iq",
|
|
|
|
xmlns: nil,
|
2024-12-16 13:11:46 +00:00
|
|
|
attributes: attributes,
|
2024-06-19 15:06:39 +00:00
|
|
|
content: nil,
|
|
|
|
nodes: [payload]
|
|
|
|
)
|
|
|
|
return Stanza(wrap: req)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private extension Stanza {
|
|
|
|
func warn() {
|
|
|
|
print("Something went wrong! with \(wrapped.stringRepresentation.prettyStr)")
|
|
|
|
}
|
|
|
|
}
|