aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAdelyn Breelove <[email protected]>2019-01-24 11:59:13 -0700
committerAdelyn Breelove <[email protected]>2019-01-24 11:59:13 -0700
commit2d61d1ffd77940eebd4e865ba1429c5798ed0b7c (patch)
tree08327e19f4047eace5d88dce7dde2997cf119406 /lib
parentImprove HTTP stuff (diff)
downloaddisml-2d61d1ffd77940eebd4e865ba1429c5798ed0b7c.tar.xz
disml-2d61d1ffd77940eebd4e865ba1429c5798ed0b7c.zip
Start of an event dispatch rework
Diffstat (limited to 'lib')
-rw-r--r--lib/disml.ml36
-rw-r--r--lib/dispatch.ml71
-rw-r--r--lib/dispatch.mli77
-rw-r--r--lib/dune7
-rw-r--r--lib/event.ml167
-rw-r--r--lib/event.mli72
-rw-r--r--lib/impl.ml8
-rw-r--r--lib/models/channel/message/message_t.ml22
-rw-r--r--lib/models/channel/message/message_t.mli23
-rw-r--r--lib/models/event_models.ml347
-rw-r--r--lib/models/id/message_id.ml3
-rw-r--r--lib/models/id/message_id.mli3
-rw-r--r--lib/models/id/role_id.ml3
-rw-r--r--lib/models/id/role_id.mli3
-rw-r--r--lib/models/id/user_id.ml1
-rw-r--r--lib/models/id/user_id.mli2
-rw-r--r--lib/models/id/user_id_t.ml3
-rw-r--r--lib/models/id/user_id_t.mli3
-rw-r--r--lib/models/user/user.mli4
-rw-r--r--lib/s.ml8
20 files changed, 596 insertions, 267 deletions
diff --git a/lib/disml.ml b/lib/disml.ml
index 3274342..021ceb0 100644
--- a/lib/disml.ml
+++ b/lib/disml.ml
@@ -2,19 +2,23 @@ module Client = Client
module Http = Http
module Sharder = Sharder
-module Activity = Activity
-module Attachment = Attachment
-module Ban = Ban
-module Channel = Channel
-module Channel_id = Channel_id
-module Embed = Embed
-module Emoji = Emoji
-module Guild = Guild
-module Guild_id = Guild_id
-module Member = Member
-module Message = Message
-module Presence = Presence
-module Reaction = Reaction
-module Role = Role
-module Snowflake = Snowflake
-module User = User \ No newline at end of file
+module Models = struct
+ module Activity = Activity
+ module Attachment = Attachment
+ module Ban = Ban
+ module Channel = Channel
+ module Channel_id = Channel_id
+ module Embed = Embed
+ module Emoji = Emoji
+ module Guild = Guild
+ module Guild_id = Guild_id
+ module Member = Member
+ module Message = Message
+ module Presence = Presence
+ module Reaction = Reaction
+ module Role = Role
+ module Snowflake = Snowflake
+ module User = User
+
+ module Event = Event_models
+end \ No newline at end of file
diff --git a/lib/dispatch.ml b/lib/dispatch.ml
index df1153e..ef53442 100644
--- a/lib/dispatch.ml
+++ b/lib/dispatch.ml
@@ -1,35 +1,36 @@
-let hello = ref (fun (_:Yojson.Safe.json) -> ())
-let ready = ref (fun (_:Yojson.Safe.json) -> ())
-let resumed = ref (fun (_:Yojson.Safe.json) -> ())
-let invalid_session = ref (fun (_:Yojson.Safe.json) -> ())
-let channel_create = ref (fun (_:Channel_t.t) -> ())
-let channel_update = ref (fun (_:Channel_t.t) -> ())
-let channel_delete = ref (fun (_:Channel_t.t) -> ())
-let channel_pins_update = ref (fun (_:Yojson.Safe.json) -> ())
-let guild_create = ref (fun (_:Guild_t.t) -> ())
-let guild_update = ref (fun (_:Guild_t.t) -> ())
-let guild_delete = ref (fun (_:Guild_t.t) -> ())
-let member_ban = ref (fun (_:Ban_t.t) -> ())
-let member_unban = ref (fun (_:Ban_t.t) -> ())
-let guild_emojis_update = ref (fun (_:Yojson.Safe.json) -> ())
-let integrations_update = ref (fun (_:Yojson.Safe.json) -> ())
-let member_join = ref (fun (_:Member_t.t) -> ())
-let member_leave = ref (fun (_:Member_t.member_wrapper) -> ())
-let member_update = ref (fun (_:Member_t.member_update) -> ())
-let members_chunk = ref (fun (_:Member_t.t list) -> ())
-let role_create = ref (fun (_:Role_t.t) -> ())
-let role_update = ref (fun (_:Role_t.t) -> ())
-let role_delete = ref (fun (_:Role_t.t) -> ())
-let message_create = ref (fun (_:Message_t.t) -> ())
-let message_update = ref (fun (_:Message_t.message_update) -> ())
-let message_delete = ref (fun (_:Snowflake.t) (_:Snowflake.t) -> ())
-let message_delete_bulk = ref (fun (_:Snowflake.t list) -> ())
-let reaction_add = ref (fun (_:Reaction_t.reaction_event) -> ())
-let reaction_remove = ref (fun (_:Reaction_t.reaction_event) -> ())
-let reaction_bulk_remove = ref (fun (_:Reaction_t.t list) -> ())
-let presence_update = ref (fun (_:Presence.t) -> ())
-let typing_start = ref (fun (_:Yojson.Safe.json) -> ())
-let user_update = ref (fun (_:Yojson.Safe.json) -> ())
-let voice_state_update = ref (fun (_:Yojson.Safe.json) -> ())
-let voice_server_update = ref (fun (_:Yojson.Safe.json) -> ())
-let webhooks_update = ref (fun (_:Yojson.Safe.json) -> ()) \ No newline at end of file
+open Event_models
+
+let ready = ref (fun (_:Ready.t) -> ())
+let resumed = ref (fun (_:Resumed.t) -> ())
+let channel_create = ref (fun (_:ChannelCreate.t) -> ())
+let channel_update = ref (fun (_:ChannelUpdate.t) -> ())
+let channel_delete = ref (fun (_:ChannelDelete.t) -> ())
+let channel_pins_update = ref (fun (_:ChannelPinsUpdate.t) -> ())
+let guild_create = ref (fun (_:GuildCreate.t) -> ())
+let guild_update = ref (fun (_:GuildUpdate.t) -> ())
+let guild_delete = ref (fun (_:GuildDelete.t) -> ())
+let member_ban = ref (fun (_:GuildBanAdd.t) -> ())
+let member_unban = ref (fun (_:GuildBanRemove.t) -> ())
+let guild_emojis_update = ref (fun (_:GuildEmojisUpdate.t) -> ())
+(* let integrations_update = ref (fun (_:Yojson.Safe.json) -> ()) *)
+let member_join = ref (fun (_:GuildMemberAdd.t) -> ())
+let member_leave = ref (fun (_:GuildMemberRemove.t) -> ())
+let member_update = ref (fun (_:GuildMemberUpdate.t) -> ())
+let members_chunk = ref (fun (_:GuildMembersChunk.t) -> ())
+let role_create = ref (fun (_:GuildRoleCreate.t) -> ())
+let role_update = ref (fun (_:GuildRoleUpdate.t) -> ())
+let role_delete = ref (fun (_:GuildRoleDelete.t) -> ())
+let message_create = ref (fun (_:MessageCreate.t) -> ())
+let message_update = ref (fun (_:MessageUpdate.t) -> ())
+let message_delete = ref (fun (_:MessageDelete.t) -> ())
+let message_delete_bulk = ref (fun (_:MessageDeleteBulk.t) -> ())
+let reaction_add = ref (fun (_:ReactionAdd.t) -> ())
+let reaction_remove = ref (fun (_:ReactionRemove.t) -> ())
+let reaction_remove_all = ref (fun (_:ReactionRemoveAll.t) -> ())
+let presence_update = ref (fun (_:PresenceUpdate.t) -> ())
+let typing_start = ref (fun (_:TypingStart.t) -> ())
+let user_update = ref (fun (_:UserUpdate.t) -> ())
+(* let voice_state_update = ref (fun (_:Yojson.Safe.json) -> ()) *)
+(* let voice_server_update = ref (fun (_:Yojson.Safe.json) -> ()) *)
+let webhook_update = ref (fun (_:WebhookUpdate.t) -> ())
+let unknown = ref (fun (_:Unknown.t) -> ()) \ No newline at end of file
diff --git a/lib/dispatch.mli b/lib/dispatch.mli
index c1d2346..78126b7 100644
--- a/lib/dispatch.mli
+++ b/lib/dispatch.mli
@@ -17,103 +17,104 @@
]}
*)
-(** Dispatched when connecting to the gateway, most users will have no use for this. *)
-val hello : (Yojson.Safe.json -> unit) ref
+open Event_models
(** Dispatched when each shard receives READY from discord after identifying on the gateway. Other event dispatch is received after this. *)
-val ready : (Yojson.Safe.json -> unit) ref
+val ready : (Ready.t -> unit) ref
(** Dispatched when successfully reconnecting to the gateway. *)
-val resumed : (Yojson.Safe.json -> unit) ref
-
-(** Dispatched when Discord decides a session is invalid, much like {!Client.hello} this is not very useful for most people. *)
-val invalid_session : (Yojson.Safe.json -> unit) ref
+val resumed : (Resumed.t -> unit) ref
(** Dispatched when a channel is created which is visible to the bot. *)
-val channel_create : (Channel.t -> unit) ref
+val channel_create : (ChannelCreate.t -> unit) ref
(** Dispatched when a channel visible to the bot is changed. *)
-val channel_update : (Channel.t -> unit) ref
+val channel_update : (ChannelUpdate.t -> unit) ref
(** Dispatched when a channel visible to the bot is deleted. *)
-val channel_delete : (Channel.t -> unit) ref
+val channel_delete : (ChannelDelete.t -> unit) ref
(** Dispatched when messages are pinned or unpinned from a a channel. *)
-val channel_pins_update : (Yojson.Safe.json -> unit) ref
+val channel_pins_update : (ChannelPinsUpdate.t -> unit) ref
(** Dispatched when the bot joins a guild, and during startup. *)
-val guild_create : (Guild.t -> unit) ref
+val guild_create : (GuildCreate.t -> unit) ref
(** Dispatched when a guild the bot is in is edited. *)
-val guild_update : (Guild.t -> unit) ref
+val guild_update : (GuildUpdate.t -> unit) ref
(** Dispatched when the bot is removed from a guild. *)
-val guild_delete : (Guild.t -> unit) ref
+val guild_delete : (GuildDelete.t -> unit) ref
(** Dispatched when a member is banned. *)
-val member_ban : (Ban.t -> unit) ref
+val member_ban : (GuildBanAdd.t -> unit) ref
(** Dispatched when a member is unbanned. *)
-val member_unban : (Ban.t -> unit) ref
+val member_unban : (GuildBanRemove.t -> unit) ref
(** Dispatched when emojis are added or removed from a guild. *)
-val guild_emojis_update : (Yojson.Safe.json -> unit) ref
+val guild_emojis_update : (GuildEmojisUpdate.t -> unit) ref
(** Dispatched when a guild's integrations are updated. *)
-val integrations_update : (Yojson.Safe.json -> unit) ref
+(* val integrations_update : (Yojson.Safe.json -> unit) ref *)
(** Dispatched when a member joins a guild. *)
-val member_join : (Member.t -> unit) ref
+val member_join : (GuildMemberAdd.t -> unit) ref
(** Dispatched when a member leaves a guild. Is Dispatched alongside {!Client.member_ban} when a user is banned. *)
-val member_leave : (Member.member_wrapper -> unit) ref
+val member_leave : (GuildMemberRemove.t -> unit) ref
(** Dispatched when a member object is updated. *)
-val member_update : (Member.member_update -> unit) ref
+val member_update : (GuildMemberUpdate.t -> unit) ref
(** Dispatched when requesting guild members through {!Client.request_guild_members} *)
-val members_chunk : (Member.t list -> unit) ref
+val members_chunk : (GuildMembersChunk.t -> unit) ref
(** Dispatched when a role is created. *)
-val role_create : (Role.t -> unit) ref
+val role_create : (GuildRoleCreate.t -> unit) ref
(** Dispatched when a role is edited. *)
-val role_update : (Role.t -> unit) ref
+val role_update : (GuildRoleUpdate.t -> unit) ref
(** Dispatched when a role is deleted. *)
-val role_delete : (Role.t -> unit) ref
+val role_delete : (GuildRoleDelete.t -> unit) ref
(** Dispatched when a message is sent. *)
-val message_create : (Message.t -> unit) ref
+val message_create : (MessageCreate.t -> unit) ref
(** Dispatched when a message is edited. This does not necessarily mean the content changed. *)
-val message_update : (Message.message_update -> unit) ref
+val message_update : (MessageUpdate.t -> unit) ref
(** Dispatched when a message is deleted. *)
-val message_delete : (Snowflake.t -> Snowflake.t -> unit) ref
+val message_delete : (MessageDelete.t -> unit) ref
(** Dispatched when messages are bulk deleted. *)
-val message_delete_bulk : (Snowflake.t list -> unit) ref
+val message_delete_bulk : (MessageDeleteBulk.t -> unit) ref
(** Dispatched when a rection is added to a message. *)
-val reaction_add : (Reaction.reaction_event -> unit) ref
+val reaction_add : (ReactionAdd.t -> unit) ref
(** Dispatched when a reaction is removed from a message. *)
-val reaction_remove : (Reaction.reaction_event -> unit) ref
+val reaction_remove : (ReactionRemove.t -> unit) ref
(** Dispatched when all reactions are cleared from a message. *)
-val reaction_bulk_remove : (Reaction.t list -> unit) ref
+val reaction_remove_all : (ReactionRemoveAll.t -> unit) ref
(** Dispatched when a user updates their presence. *)
-val presence_update : (Presence.t -> unit) ref
+val presence_update : (PresenceUpdate.t -> unit) ref
(** Dispatched when a typing indicator is displayed. *)
-val typing_start : (Yojson.Safe.json -> unit) ref
+val typing_start : (TypingStart.t -> unit) ref
(** Dispatched when the current user is updated. You most likely want {!Client.member_update} or {!Client.presence_update} instead. *)
-val user_update : (Yojson.Safe.json -> unit) ref
+val user_update : (UserUpdate.t -> unit) ref
+
+(** Dispatched when a webhook is updated. *)
+val webhook_update : (WebhookUpdate.t -> unit) ref
+
+(** Dispatched as a fallback for unknown events. *)
+val unknown : (Unknown.t -> unit) ref
(**/**)
-val voice_state_update : (Yojson.Safe.json -> unit) ref
-val voice_server_update : (Yojson.Safe.json -> unit) ref
-val webhooks_update : (Yojson.Safe.json -> unit) ref \ No newline at end of file
+(* val voice_state_update : (Yojson.Safe.json -> unit) ref *)
+(* val voice_server_update : (Yojson.Safe.json -> unit) ref *) \ No newline at end of file
diff --git a/lib/dune b/lib/dune
index ea0142e..95f3794 100644
--- a/lib/dune
+++ b/lib/dune
@@ -11,12 +11,13 @@
emoji
guild guild_t guild_id guild_id_t
member member_t
- message message_t
+ message message_t message_id
presence
reaction reaction_t
- role role_t
+ role role_t role_id
snowflake
- user user_t
+ user user_t user_id user_id_t
+ event_models
client client_options disml dispatch endpoints event http impl opcode rl s sharder
)
(libraries core async_ssl cohttp-async logs yojson websocket-async zlib ppx_deriving_yojson.runtime)
diff --git a/lib/event.ml b/lib/event.ml
index 7082858..468acc6 100644
--- a/lib/event.ml
+++ b/lib/event.ml
@@ -1,87 +1,81 @@
open Core
-
-exception Invalid_event of string
+open Event_models
type t =
-| HELLO of Yojson.Safe.json
-| READY of Yojson.Safe.json
-| RESUMED of Yojson.Safe.json
-| INVALID_SESSION of Yojson.Safe.json
-| CHANNEL_CREATE of Channel_t.t
-| CHANNEL_UPDATE of Channel_t.t
-| CHANNEL_DELETE of Channel_t.t
-| CHANNEL_PINS_UPDATE of Yojson.Safe.json
-| GUILD_CREATE of Guild_t.t
-| GUILD_UPDATE of Guild_t.t
-| GUILD_DELETE of Guild_t.t
-| GUILD_BAN_ADD of Ban_t.t
-| GUILD_BAN_REMOVE of Ban_t.t
-| GUILD_EMOJIS_UPDATE of Yojson.Safe.json
-| GUILD_INTEGRATIONS_UPDATE of Yojson.Safe.json
-| GUILD_MEMBER_ADD of Member_t.t
-| GUILD_MEMBER_REMOVE of Member_t.member_wrapper
-| GUILD_MEMBER_UPDATE of Member_t.member_update
-| GUILD_MEMBERS_CHUNK of Member_t.t list
-| GUILD_ROLE_CREATE of Role_t.t
-| GUILD_ROLE_UPDATE of Role_t.t
-| GUILD_ROLE_DELETE of Role_t.t
-| MESSAGE_CREATE of Message_t.t
-| MESSAGE_UPDATE of Message_t.message_update
-| MESSAGE_DELETE of Snowflake.t * Snowflake.t
-| MESSAGE_DELETE_BULK of Snowflake.t list
-| MESSAGE_REACTION_ADD of Reaction_t.reaction_event
-| MESSAGE_REACTION_REMOVE of Reaction_t.reaction_event
-| MESSAGE_REACTION_REMOVE_ALL of Reaction_t.t list
-| PRESENCE_UPDATE of Presence.t
-| TYPING_START of Yojson.Safe.json
-| USER_UPDATE of Yojson.Safe.json
-| VOICE_STATE_UPDATE of Yojson.Safe.json
-| VOICE_SERVER_UPDATE of Yojson.Safe.json
-| WEBHOOKS_UPDATE of Yojson.Safe.json
+| READY of Ready.t
+| RESUMED of Resumed.t
+| CHANNEL_CREATE of ChannelCreate.t
+| CHANNEL_UPDATE of ChannelUpdate.t
+| CHANNEL_DELETE of ChannelDelete.t
+| CHANNEL_PINS_UPDATE of ChannelPinsUpdate.t
+| GUILD_CREATE of GuildCreate.t
+| GUILD_UPDATE of GuildUpdate.t
+| GUILD_DELETE of GuildDelete.t
+| GUILD_BAN_ADD of GuildBanAdd.t
+| GUILD_BAN_REMOVE of GuildBanRemove.t
+| GUILD_EMOJIS_UPDATE of GuildEmojisUpdate.t
+(* | GUILD_INTEGRATIONS_UPDATE of Yojson.Safe.json *)
+| GUILD_MEMBER_ADD of GuildMemberAdd.t
+| GUILD_MEMBER_REMOVE of GuildMemberRemove.t
+| GUILD_MEMBER_UPDATE of GuildMemberUpdate.t
+| GUILD_MEMBERS_CHUNK of GuildMembersChunk.t
+| GUILD_ROLE_CREATE of GuildRoleCreate.t
+| GUILD_ROLE_UPDATE of GuildRoleUpdate.t
+| GUILD_ROLE_DELETE of GuildRoleDelete.t
+| MESSAGE_CREATE of MessageCreate.t
+| MESSAGE_UPDATE of MessageUpdate.t
+| MESSAGE_DELETE of MessageDelete.t
+| MESSAGE_DELETE_BULK of MessageDeleteBulk.t
+| REACTION_ADD of ReactionAdd.t
+| REACTION_REMOVE of ReactionRemove.t
+| REACTION_REMOVE_ALL of ReactionRemoveAll.t
+| PRESENCE_UPDATE of PresenceUpdate.t
+| TYPING_START of TypingStart.t
+| USER_UPDATE of UserUpdate.t
+(* | VOICE_STATE_UPDATE of Yojson.Safe.json *)
+(* | VOICE_SERVER_UPDATE of Yojson.Safe.json *)
+| WEBHOOK_UPDATE of WebhookUpdate.t
+| UNKNOWN of Unknown.t
let event_of_yojson ~contents t = match t with
- | "HELLO" -> HELLO contents
- | "READY" -> READY contents
- | "RESUMED" -> RESUMED contents
- | "INVALID_SESSION" -> INVALID_SESSION contents
- | "CHANNEL_CREATE" -> CHANNEL_CREATE (Channel_t.(channel_wrapper_of_yojson_exn contents |> wrap))
- | "CHANNEL_UPDATE" -> CHANNEL_UPDATE (Channel_t.(channel_wrapper_of_yojson_exn contents |> wrap))
- | "CHANNEL_DELETE" -> CHANNEL_DELETE (Channel_t.(channel_wrapper_of_yojson_exn contents |> wrap))
- | "CHANNEL_PINS_UPDATE" -> CHANNEL_PINS_UPDATE contents
- | "GUILD_CREATE" -> GUILD_CREATE (Guild_t.(pre_of_yojson_exn contents |> wrap))
- | "GUILD_UPDATE" -> GUILD_UPDATE (Guild_t.(pre_of_yojson_exn contents |> wrap))
- | "GUILD_DELETE" -> GUILD_DELETE (Guild_t.(pre_of_yojson_exn contents |> wrap))
- | "GUILD_BAN_ADD" -> GUILD_BAN_ADD (Ban_t.of_yojson_exn contents)
- | "GUILD_BAN_REMOVE" -> GUILD_BAN_REMOVE (Ban_t.of_yojson_exn contents)
- | "GUILD_EMOJIS_UPDATE" -> GUILD_EMOJIS_UPDATE contents
- | "GUILD_INTEGRATIONS_UPDATE" -> GUILD_INTEGRATIONS_UPDATE contents
- | "GUILD_MEMBER_ADD" -> GUILD_MEMBER_ADD (Member_t.of_yojson_exn contents)
- | "GUILD_MEMBER_REMOVE" -> GUILD_MEMBER_REMOVE (Member_t.member_wrapper_of_yojson_exn contents)
- | "GUILD_MEMBER_UPDATE" -> GUILD_MEMBER_UPDATE (Member_t.member_update_of_yojson_exn contents)
- | "GUILD_MEMBERS_CHUNK" -> GUILD_MEMBERS_CHUNK (Yojson.Safe.Util.to_list contents |> List.map ~f:Member_t.of_yojson_exn)
- | "GUILD_ROLE_CREATE" -> GUILD_ROLE_CREATE (let Role_t.{guild_id;role} = Role_t.role_update_of_yojson_exn contents in Role_t.wrap ~guild_id role)
- | "GUILD_ROLE_UPDATE" -> GUILD_ROLE_UPDATE (let Role_t.{guild_id;role} = Role_t.role_update_of_yojson_exn contents in Role_t.wrap ~guild_id role)
- | "GUILD_ROLE_DELETE" -> GUILD_ROLE_DELETE (let Role_t.{guild_id;role} = Role_t.role_update_of_yojson_exn contents in Role_t.wrap ~guild_id role)
- | "MESSAGE_CREATE" -> MESSAGE_CREATE (Message_t.of_yojson_exn contents)
- | "MESSAGE_UPDATE" -> MESSAGE_UPDATE (Message_t.message_update_of_yojson_exn contents)
- | "MESSAGE_DELETE" -> MESSAGE_DELETE (Yojson.Safe.Util.(member "id" contents |> Snowflake.of_yojson_exn), Yojson.Safe.Util.(member "channel_id" contents |> Snowflake.of_yojson_exn))
- | "MESSAGE_DELETE_BULK" -> MESSAGE_DELETE_BULK (Yojson.Safe.Util.(member "ids" contents |> to_list) |> List.map ~f:Snowflake.of_yojson_exn)
- | "MESSAGE_REACTION_ADD" -> MESSAGE_REACTION_ADD (Reaction_t.reaction_event_of_yojson_exn contents)
- | "MESSAGE_REACTION_REMOVE" -> MESSAGE_REACTION_REMOVE (Reaction_t.reaction_event_of_yojson_exn contents)
- | "MESSAGE_REACTION_REMOVE_ALL" -> MESSAGE_REACTION_REMOVE_ALL (Yojson.Safe.Util.to_list contents |> List.map ~f:Reaction_t.of_yojson_exn)
- | "PRESENCE_UPDATE" -> PRESENCE_UPDATE (Presence.of_yojson_exn contents)
- | "TYPING_START" -> TYPING_START contents
- | "USER_UPDATE" -> USER_UPDATE contents
- | "VOICE_STATE_UPDATE" -> VOICE_STATE_UPDATE contents
- | "VOICE_SERVER_UPDATE" -> VOICE_SERVER_UPDATE contents
- | "WEBHOOKS_UPDATE" -> WEBHOOKS_UPDATE contents
- | s -> raise @@ Invalid_event s
+ | "READY" -> READY Ready.(deserialize contents)
+ | "RESUMED" -> RESUMED Resumed.(deserialize contents)
+ | "CHANNEL_CREATE" -> CHANNEL_CREATE ChannelCreate.(deserialize contents)
+ | "CHANNEL_UPDATE" -> CHANNEL_UPDATE ChannelUpdate.(deserialize contents)
+ | "CHANNEL_DELETE" -> CHANNEL_DELETE ChannelDelete.(deserialize contents)
+ | "CHANNEL_PINS_UPDATE" -> CHANNEL_PINS_UPDATE ChannelPinsUpdate.(deserialize contents)
+ | "GUILD_CREATE" -> GUILD_CREATE GuildCreate.(deserialize contents)
+ | "GUILD_UPDATE" -> GUILD_UPDATE GuildUpdate.(deserialize contents)
+ | "GUILD_DELETE" -> GUILD_DELETE GuildDelete.(deserialize contents)
+ | "GUILD_BAN_ADD" -> GUILD_BAN_ADD GuildBanAdd.(deserialize contents)
+ | "GUILD_BAN_REMOVE" -> GUILD_BAN_REMOVE GuildBanRemove.(deserialize contents)
+ | "GUILD_EMOJIS_UPDATE" -> GUILD_EMOJIS_UPDATE GuildEmojisUpdate.(deserialize contents)
+ (* | "GUILD_INTEGRATIONS_UPDATE" -> GUILD_INTEGRATIONS_UPDATE contents *)
+ | "GUILD_MEMBER_ADD" -> GUILD_MEMBER_ADD GuildMemberAdd.(deserialize contents)
+ | "GUILD_MEMBER_REMOVE" -> GUILD_MEMBER_REMOVE GuildMemberRemove.(deserialize contents)
+ | "GUILD_MEMBER_UPDATE" -> GUILD_MEMBER_UPDATE GuildMemberUpdate.(deserialize contents)
+ | "GUILD_MEMBERS_CHUNK" -> GUILD_MEMBERS_CHUNK GuildMembersChunk.(deserialize contents)
+ | "GUILD_ROLE_CREATE" -> GUILD_ROLE_CREATE GuildRoleCreate.(deserialize contents)
+ | "GUILD_ROLE_UPDATE" -> GUILD_ROLE_UPDATE GuildRoleUpdate.(deserialize contents)
+ | "GUILD_ROLE_DELETE" -> GUILD_ROLE_DELETE GuildRoleDelete.(deserialize contents)
+ | "MESSAGE_CREATE" -> MESSAGE_CREATE MessageCreate.(deserialize contents)
+ | "MESSAGE_UPDATE" -> MESSAGE_UPDATE MessageUpdate.(deserialize contents)
+ | "MESSAGE_DELETE" -> MESSAGE_DELETE MessageDelete.(deserialize contents)
+ | "MESSAGE_DELETE_BULK" -> MESSAGE_DELETE_BULK MessageDeleteBulk.(deserialize contents)
+ | "MESSAGE_REACTION_ADD" -> REACTION_ADD ReactionAdd.(deserialize contents)
+ | "MESSAGE_REACTION_REMOVE" -> REACTION_REMOVE ReactionRemove.(deserialize contents)
+ | "MESSAGE_REACTION_REMOVE_ALL" -> REACTION_REMOVE_ALL ReactionRemoveAll.(deserialize contents)
+ | "PRESENCE_UPDATE" -> PRESENCE_UPDATE PresenceUpdate.(deserialize contents)
+ | "TYPING_START" -> TYPING_START TypingStart.(deserialize contents)
+ | "USER_UPDATE" -> USER_UPDATE UserUpdate.(deserialize contents)
+ (* | "VOICE_STATE_UPDATE" -> VOICE_STATE_UPDATE contents *)
+ (* | "VOICE_SERVER_UPDATE" -> VOICE_SERVER_UPDATE contents *)
+ | "WEBHOOK_UPDATE" -> WEBHOOK_UPDATE WebhookUpdate.(deserialize contents)
+ | s -> UNKNOWN Unknown.(deserialize s contents)
let dispatch ev = match ev with
- | HELLO d -> !Dispatch.hello d
| READY d -> !Dispatch.ready d
| RESUMED d -> !Dispatch.resumed d
- | INVALID_SESSION d -> !Dispatch.invalid_session d
| CHANNEL_CREATE d -> !Dispatch.channel_create d
| CHANNEL_UPDATE d -> !Dispatch.channel_update d
| CHANNEL_DELETE d -> !Dispatch.channel_delete d
@@ -92,7 +86,7 @@ let dispatch ev = match ev with
| GUILD_BAN_ADD d -> !Dispatch.member_ban d
| GUILD_BAN_REMOVE d -> !Dispatch.member_unban d
| GUILD_EMOJIS_UPDATE d -> !Dispatch.guild_emojis_update d
- | GUILD_INTEGRATIONS_UPDATE d -> !Dispatch.integrations_update d
+ (* | GUILD_INTEGRATIONS_UPDATE d -> !Dispatch.integrations_update d *)
| GUILD_MEMBER_ADD d -> !Dispatch.member_join d
| GUILD_MEMBER_REMOVE d -> !Dispatch.member_leave d
| GUILD_MEMBER_UPDATE d -> !Dispatch.member_update d
@@ -102,20 +96,19 @@ let dispatch ev = match ev with
| GUILD_ROLE_DELETE d -> !Dispatch.role_delete d
| MESSAGE_CREATE d -> !Dispatch.message_create d
| MESSAGE_UPDATE d -> !Dispatch.message_update d
- | MESSAGE_DELETE (d,e) -> !Dispatch.message_delete d e
+ | MESSAGE_DELETE d -> !Dispatch.message_delete d
| MESSAGE_DELETE_BULK d -> !Dispatch.message_delete_bulk d
- | MESSAGE_REACTION_ADD d -> !Dispatch.reaction_add d
- | MESSAGE_REACTION_REMOVE d -> !Dispatch.reaction_remove d
- | MESSAGE_REACTION_REMOVE_ALL d -> !Dispatch.reaction_bulk_remove d
+ | REACTION_ADD d -> !Dispatch.reaction_add d
+ | REACTION_REMOVE d -> !Dispatch.reaction_remove d
+ | REACTION_REMOVE_ALL d -> !Dispatch.reaction_remove_all d
| PRESENCE_UPDATE d -> !Dispatch.presence_update d
| TYPING_START d -> !Dispatch.typing_start d
| USER_UPDATE d -> !Dispatch.user_update d
- | VOICE_STATE_UPDATE d -> !Dispatch.voice_state_update d
- | VOICE_SERVER_UPDATE d -> !Dispatch.voice_server_update d
- | WEBHOOKS_UPDATE d -> !Dispatch.webhooks_update d
+ (* | VOICE_STATE_UPDATE d -> !Dispatch.voice_state_update d *)
+ (* | VOICE_SERVER_UPDATE d -> !Dispatch.voice_server_update d *)
+ | WEBHOOK_UPDATE d -> !Dispatch.webhook_update d
+ | UNKNOWN d -> !Dispatch.unknown d
let handle_event ~ev contents =
- try
- event_of_yojson ~contents ev
- |> dispatch
- with Invalid_event ev -> Logs.debug (fun m -> m "Unknown event: %s" ev); \ No newline at end of file
+ event_of_yojson ~contents ev
+ |> dispatch \ No newline at end of file
diff --git a/lib/event.mli b/lib/event.mli
index f6cdf14..9e05569 100644
--- a/lib/event.mli
+++ b/lib/event.mli
@@ -1,45 +1,43 @@
(** Barebones of event dispatching. Most users will have no reason to look here. *)
-(** Used internally when received an unknown event. Is caught and logged. *)
-exception Invalid_event of string
+open Event_models
(** Event dispatch type wrapper. Used internally. *)
type t =
-| HELLO of Yojson.Safe.json
-| READY of Yojson.Safe.json
-| RESUMED of Yojson.Safe.json
-| INVALID_SESSION of Yojson.Safe.json
-| CHANNEL_CREATE of Channel_t.t
-| CHANNEL_UPDATE of Channel_t.t
-| CHANNEL_DELETE of Channel_t.t
-| CHANNEL_PINS_UPDATE of Yojson.Safe.json
-| GUILD_CREATE of Guild_t.t
-| GUILD_UPDATE of Guild_t.t
-| GUILD_DELETE of Guild_t.t
-| GUILD_BAN_ADD of Ban_t.t
-| GUILD_BAN_REMOVE of Ban_t.t
-| GUILD_EMOJIS_UPDATE of Yojson.Safe.json
-| GUILD_INTEGRATIONS_UPDATE of Yojson.Safe.json
-| GUILD_MEMBER_ADD of Member_t.t
-| GUILD_MEMBER_REMOVE of Member_t.member_wrapper
-| GUILD_MEMBER_UPDATE of Member_t.member_update
-| GUILD_MEMBERS_CHUNK of Member_t.t list
-| GUILD_ROLE_CREATE of Role_t.t
-| GUILD_ROLE_UPDATE of Role_t.t
-| GUILD_ROLE_DELETE of Role_t.t
-| MESSAGE_CREATE of Message_t.t
-| MESSAGE_UPDATE of Message_t.message_update
-| MESSAGE_DELETE of Snowflake.t * Snowflake.t
-| MESSAGE_DELETE_BULK of Snowflake.t list
-| MESSAGE_REACTION_ADD of Reaction_t.reaction_event
-| MESSAGE_REACTION_REMOVE of Reaction_t.reaction_event
-| MESSAGE_REACTION_REMOVE_ALL of Reaction_t.t list
-| PRESENCE_UPDATE of Presence.t
-| TYPING_START of Yojson.Safe.json
-| USER_UPDATE of Yojson.Safe.json
-| VOICE_STATE_UPDATE of Yojson.Safe.json
-| VOICE_SERVER_UPDATE of Yojson.Safe.json
-| WEBHOOKS_UPDATE of Yojson.Safe.json
+| READY of Ready.t
+| RESUMED of Resumed.t
+| CHANNEL_CREATE of ChannelCreate.t
+| CHANNEL_UPDATE of ChannelUpdate.t
+| CHANNEL_DELETE of ChannelDelete.t
+| CHANNEL_PINS_UPDATE of ChannelPinsUpdate.t
+| GUILD_CREATE of GuildCreate.t
+| GUILD_UPDATE of GuildUpdate.t
+| GUILD_DELETE of GuildDelete.t
+| GUILD_BAN_ADD of GuildBanAdd.t
+| GUILD_BAN_REMOVE of GuildBanRemove.t
+| GUILD_EMOJIS_UPDATE of GuildEmojisUpdate.t
+(* | GUILD_INTEGRATIONS_UPDATE of Yojson.Safe.json *)
+| GUILD_MEMBER_ADD of GuildMemberAdd.t
+| GUILD_MEMBER_REMOVE of GuildMemberRemove.t
+| GUILD_MEMBER_UPDATE of GuildMemberUpdate.t
+| GUILD_MEMBERS_CHUNK of GuildMembersChunk.t
+| GUILD_ROLE_CREATE of GuildRoleCreate.t
+| GUILD_ROLE_UPDATE of GuildRoleUpdate.t
+| GUILD_ROLE_DELETE of GuildRoleDelete.t
+| MESSAGE_CREATE of MessageCreate.t
+| MESSAGE_UPDATE of MessageUpdate.t
+| MESSAGE_DELETE of MessageDelete.t
+| MESSAGE_DELETE_BULK of MessageDeleteBulk.t
+| REACTION_ADD of ReactionAdd.t
+| REACTION_REMOVE of ReactionRemove.t
+| REACTION_REMOVE_ALL of ReactionRemoveAll.t
+| PRESENCE_UPDATE of PresenceUpdate.t
+| TYPING_START of TypingStart.t
+| USER_UPDATE of UserUpdate.t
+(* | VOICE_STATE_UPDATE of Yojson.Safe.json *)
+(* | VOICE_SERVER_UPDATE of Yojson.Safe.json *)
+| WEBHOOK_UPDATE of WebhookUpdate.t
+| UNKNOWN of Unknown.t
(** Used to convert an event string and payload into a t wrapper type. *)
val event_of_yojson : contents:Yojson.Safe.json -> string -> t
diff --git a/lib/impl.ml b/lib/impl.ml
index 573ef30..cc0f050 100644
--- a/lib/impl.ml
+++ b/lib/impl.ml
@@ -1,4 +1,4 @@
-module Channel(T : S.Has_snowflake) : S.ChannelImpl with type t := T.t = struct
+module Channel(T : S.HasSnowflake) : S.ChannelImpl with type t := T.t = struct
open Core
include T
@@ -52,7 +52,7 @@ module Channel(T : S.Has_snowflake) : S.ChannelImpl with type t := T.t = struct
Http.get_pinned_messages (get_id ch)
end
-module Guild(T : S.Has_snowflake) : S.GuildImpl with type t := T.t = struct
+module Guild(T : S.HasSnowflake) : S.GuildImpl with type t := T.t = struct
include T
let ban_user ~id ?(reason="") ?(days=0) guild =
@@ -157,4 +157,8 @@ module Guild(T : S.Has_snowflake) : S.GuildImpl with type t := T.t = struct
| Some r -> `Assoc [("reason", `String r)]
| None -> `Null
in Http.guild_ban_remove (get_id guild) id payload
+end
+
+module User(T : S.HasSnowflake) : S.UserImpl with type t := T.t = struct
+ include T
end \ No newline at end of file
diff --git a/lib/models/channel/message/message_t.ml b/lib/models/channel/message/message_t.ml
index c4253d5..47b5803 100644
--- a/lib/models/channel/message/message_t.ml
+++ b/lib/models/channel/message/message_t.ml
@@ -1,27 +1,5 @@
open Core
-type message_update = {
- id: Snowflake.t;
- author: User_t.t option [@default None];
- channel_id: Snowflake.t;
- member: Member_t.partial_member option [@default None];
- guild_id: Snowflake.t option [@default None];
- content: string option [@default None];
- timestamp: string option [@default None];
- editedimestamp: string option [@default None];
- tts: bool option [@default None];
- mention_everyone: bool option [@default None];
- mentions: Snowflake.t list [@default []];
- role_mentions: Snowflake.t list [@default []];
- attachments: Attachment.t list [@default []];
- embeds: Embed.t list [@default []];
- reactions: Snowflake.t list [@default []];
- nonce: Snowflake.t option [@default None];
- pinned: bool option [@default None];
- webhook_id: Snowflake.t option [@default None];
- kind: int option [@default None][@key "type"];
-} [@@deriving sexp, yojson { strict = false}]
-
type t = {
id: Snowflake.t;
author: User_t.t;
diff --git a/lib/models/channel/message/message_t.mli b/lib/models/channel/message/message_t.mli
index 097a705..14086fe 100644
--- a/lib/models/channel/message/message_t.mli
+++ b/lib/models/channel/message/message_t.mli
@@ -1,26 +1,3 @@
-(** Represents data sent on {{!Dispatch.member_update}member update} events. *)
-type message_update = {
- id: Snowflake.t;
- author: User_t.t option;
- channel_id: Snowflake.t;
- member: Member_t.partial_member option;
- guild_id: Snowflake.t option;
- content: string option;
- timestamp: string option;
- editedimestamp: string option;
- tts: bool option;
- mention_everyone: bool option;
- mentions: Snowflake.t list;
- role_mentions: Snowflake.t list;
- attachments: Attachment.t list;
- embeds: Embed.t list;
- reactions: Snowflake.t list;
- nonce: Snowflake.t option;
- pinned: bool option;
- webhook_id: Snowflake.t option;
- kind: int option;
-} [@@deriving sexp, yojson]
-
(** Represents a message object. *)
type t = {
id: Snowflake.t;
diff --git a/lib/models/event_models.ml b/lib/models/event_models.ml
new file mode 100644
index 0000000..6df9762
--- /dev/null
+++ b/lib/models/event_models.ml
@@ -0,0 +1,347 @@
+open Core
+
+module ChannelCreate = struct
+ type t = {
+ channel: Channel_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module ChannelDelete = struct
+ type t = {
+ channel: Channel_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module ChannelUpdate = struct
+ type t = {
+ channel: Channel_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module ChannelPinsUpdate = struct
+ type t = {
+ channel_id: Channel_id_t.t;
+ last_pin_timestamp: string option;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module ChannelRecipientAdd = struct
+ type t = {
+ channel_id: Channel_id_t.t;
+ user: User_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module ChannelRecipientRemove = struct
+ type t = {
+ channel_id: Channel_id_t.t;
+ user: User_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildBanAdd = struct
+ type t = {
+ guild_id: Guild_id_t.t;
+ user: User_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildBanRemove = struct
+ type t = {
+ guild_id: Guild_id_t.t;
+ user: User_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildCreate = struct
+ type t = {
+ guild: Guild_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+(* TODO *)
+module GuildDelete = struct
+ type t = {
+ foo: bool option [@default None];
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+(* TODO *)
+module GuildUpdate = struct
+ type t = {
+ foo: bool option [@default None];
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildEmojisUpdate = struct
+ type t = {
+ emojis: Emoji.t list;
+ guild_id: Guild_id_t.t
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildMemberAdd = struct
+ type t = {
+ guild_id: Guild_id_t.t;
+ member: Member_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildMemberRemove = struct
+ type t = {
+ guild_id: Guild_id_t.t;
+ user: User_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildMemberUpdate = struct
+ type t = {
+ guild_id: Guild_id_t.t;
+ nick: string option;
+ roles: Role_id.t list;
+ user: User_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildMembersChunk = struct
+ type t = {
+ guild_id: Guild_id_t.t;
+ members: (Snowflake.t * Member_t.t) list;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildRoleCreate = struct
+ type t = {
+ guild_id: Guild_id_t.t;
+ role: Role_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildRoleDelete = struct
+ type t = {
+ guild_id: Guild_id_t.t;
+ role_id: Role_id.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildRoleUpdate = struct
+ type t = {
+ guild_id: Guild_id_t.t;
+ role: Role_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module GuildUnavailable = struct
+ type t = {
+ guild_id: Guild_id_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module MessageCreate = struct
+ type t = {
+ message: Message_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module MessageDelete = struct
+ type t = {
+ channel_id: Channel_id_t.t;
+ message_id: Message_id.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module MessageUpdate = struct
+ type t = {
+ id: Snowflake.t;
+ author: User_t.t option [@default None];
+ channel_id: Snowflake.t;
+ member: Member_t.partial_member option [@default None];
+ guild_id: Snowflake.t option [@default None];
+ content: string option [@default None];
+ timestamp: string option [@default None];
+ editedimestamp: string option [@default None];
+ tts: bool option [@default None];
+ mention_everyone: bool option [@default None];
+ mentions: Snowflake.t list [@default []];
+ role_mentions: Snowflake.t list [@default []];
+ attachments: Attachment.t list [@default []];
+ embeds: Embed.t list [@default []];
+ reactions: Snowflake.t list [@default []];
+ nonce: Snowflake.t option [@default None];
+ pinned: bool option [@default None];
+ webhook_id: Snowflake.t option [@default None];
+ kind: int option [@default None][@key "type"];
+ } [@@deriving sexp, yojson { strict = false}]
+
+ let deserialize = of_yojson_exn
+end
+
+module MessageDeleteBulk = struct
+ type t = {
+ channel_id: Channel_id_t.t;
+ ids: Message_id.t list;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module PresenceUpdate = struct
+ type t = {
+ guild_id: Guild_id_t.t option;
+ presence: Presence.t;
+ roles: Role_id.t list option;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+(* module PresencesReplace = struct
+ type t =
+
+ let deserialize = of_yojson_exn
+end *)
+
+module ReactionAdd = struct
+ type t = {
+ reaction: Reaction_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module ReactionRemove = struct
+ type t = {
+ reaction: Reaction_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module ReactionRemoveAll = struct
+ type t = {
+ channel_id: Channel_id_t.t;
+ message_id: Message_id.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module Ready = struct
+ type t = {
+ foo: bool option [@default None];
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module Resumed = struct
+ type t = {
+ trace: string option list;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module TypingStart = struct
+ type t = {
+ channel_id: Channel_id_t.t;
+ timestamp: int;
+ user_id: User_id_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module UserUpdate = struct
+ type t = {
+ user: User_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module WebhookUpdate = struct
+ type t = {
+ channel_id: Channel_id_t.t;
+ guild_id: Guild_id_t.t;
+ } [@@deriving sexp, yojson]
+
+ let deserialize = of_yojson_exn
+end
+
+module Unknown = struct
+ type t = {
+ kind: string;
+ value: Yojson.Safe.json;
+ } [@@deriving yojson]
+
+ let deserialize kind value = { kind; value; }
+end
+
+(* module VoiceHeartbeat = struct
+
+end
+
+module VoiceHello = struct
+
+end
+
+module VoiceServerUpdate = struct
+
+end
+
+module VoiceSessionDescription = struct
+
+end
+
+module VoiceSpeaking = struct
+
+end
+
+module VoiceStateUpdate = struct
+
+end *) \ No newline at end of file
diff --git a/lib/models/id/message_id.ml b/lib/models/id/message_id.ml
new file mode 100644
index 0000000..377cadd
--- /dev/null
+++ b/lib/models/id/message_id.ml
@@ -0,0 +1,3 @@
+type t = [ `Message_id of Snowflake.t ] [@@deriving sexp, yojson]
+
+let get_id (`Message_id id) = id \ No newline at end of file
diff --git a/lib/models/id/message_id.mli b/lib/models/id/message_id.mli
new file mode 100644
index 0000000..da50f72
--- /dev/null
+++ b/lib/models/id/message_id.mli
@@ -0,0 +1,3 @@
+type t = [ `Message_id of Snowflake.t ] [@@deriving sexp, yojson]
+
+val get_id : t -> Snowflake.t \ No newline at end of file
diff --git a/lib/models/id/role_id.ml b/lib/models/id/role_id.ml
new file mode 100644
index 0000000..a505f33
--- /dev/null
+++ b/lib/models/id/role_id.ml
@@ -0,0 +1,3 @@
+type t = [ `Role_id of Snowflake.t ] [@@deriving sexp, yojson]
+
+let get_id (`Role_id id) = id \ No newline at end of file
diff --git a/lib/models/id/role_id.mli b/lib/models/id/role_id.mli
new file mode 100644
index 0000000..ededf3a
--- /dev/null
+++ b/lib/models/id/role_id.mli
@@ -0,0 +1,3 @@
+type t = [ `Role_id of Snowflake.t ] [@@deriving sexp, yojson]
+
+val get_id : t -> Snowflake.t \ No newline at end of file
diff --git a/lib/models/id/user_id.ml b/lib/models/id/user_id.ml
new file mode 100644
index 0000000..aba1b17
--- /dev/null
+++ b/lib/models/id/user_id.ml
@@ -0,0 +1 @@
+include Impl.User(User_id_t) \ No newline at end of file
diff --git a/lib/models/id/user_id.mli b/lib/models/id/user_id.mli
new file mode 100644
index 0000000..7fe822a
--- /dev/null
+++ b/lib/models/id/user_id.mli
@@ -0,0 +1,2 @@
+include S.UserImpl with
+ type t := User_id_t.t \ No newline at end of file
diff --git a/lib/models/id/user_id_t.ml b/lib/models/id/user_id_t.ml
new file mode 100644
index 0000000..8a6a265
--- /dev/null
+++ b/lib/models/id/user_id_t.ml
@@ -0,0 +1,3 @@
+type t = [ `User_id of Snowflake.t ] [@@deriving sexp, yojson]
+
+let get_id (`User_id id) = id \ No newline at end of file
diff --git a/lib/models/id/user_id_t.mli b/lib/models/id/user_id_t.mli
new file mode 100644
index 0000000..90211ab
--- /dev/null
+++ b/lib/models/id/user_id_t.mli
@@ -0,0 +1,3 @@
+type t = [ `User_id of Snowflake.t ] [@@deriving sexp, yojson]
+
+val get_id : t -> Snowflake.t \ No newline at end of file
diff --git a/lib/models/user/user.mli b/lib/models/user/user.mli
index 2cc6184..6e2c0f1 100644
--- a/lib/models/user/user.mli
+++ b/lib/models/user/user.mli
@@ -3,6 +3,4 @@ include module type of User_t
val tag : t -> string
val mention : t -> string
val default_avatar : t -> string
-val face : t -> string
-(* val private_channel : t -> Channel_t.t *)
-(* val send : t -> Yojson.Safe.json Deferred.Or_error.t *) \ No newline at end of file
+val face : t -> string \ No newline at end of file
diff --git a/lib/s.ml b/lib/s.ml
index 1aa69a6..64a3d17 100644
--- a/lib/s.ml
+++ b/lib/s.ml
@@ -1,6 +1,6 @@
open Async
-module type Has_snowflake = sig
+module type HasSnowflake = sig
type t [@@deriving sexp, yojson]
val get_id : t -> Snowflake.t
end
@@ -83,4 +83,10 @@ module type GuildImpl = sig
val set_name : name:string -> t -> Guild_t.t Deferred.Or_error.t
val set_icon : icon:string -> t -> Guild_t.t Deferred.Or_error.t
val unban_user : id:Snowflake.t -> ?reason:string -> t -> unit Deferred.Or_error.t
+end
+
+module type UserImpl = sig
+ type t
+ (* val private_channel : t -> Channel_t.t *)
+ (* val send : t -> Yojson.Safe.json Deferred.Or_error.t *)
end \ No newline at end of file