I'm writing a small library that would allow me to handle Sockets in a generic fashion.
I basically want to define a Socket such as it would define Emitting
& Receiving
types which would be the events we want it emit and receive, respectively.
Now, I like using enums for this sort of functionality, where I could define the Emitting
type like such:
struct MySocket {
enum Emitting {
case send(message: String)
case join(room: String)
var responseType: <?> {
switch self {
case .send: return nil
case .join: return Room.self
}
}
struct Room {
let id: String
let participants: Int
}
}
}
You'll notice that I also defined a Room
type, which is data that I know the socket should return when I emit .join(room: "room_uuid")
. There could also be other such types I could define for any future event.
The idea is that I'd then have my generic Socket
implementation which would have a convenience emit(_:)
function that would be called as such:
let socket = MySocket()
socket.emit(.join(room: "room_uuid") { data in
// type(of: data) == Emitting.Room
}
Is this at all feasible ? I know I can define a single associatedtype
which would allow me to do
protocol Event {
associatedtype Response
}
struct Socket<Emitting: Event, Receiving: Event> {
func emit(_ event: Emitting, handler: @escaping (Emitting.Response) -> Void) {
// magic
}
}
but that then prevents me from easily defining multiple events with multiple response types.
I don't know if this actually makes sense? Maybe all I need to do is define functions for each event rather than types then I have control over what response type I send back in the handler...