diff options
| author | Adelyn Breedlove <[email protected]> | 2019-03-02 18:30:46 -0700 |
|---|---|---|
| committer | Adelyn Breedlove <[email protected]> | 2019-03-02 18:30:46 -0700 |
| commit | 6163027a715b31d87e1f8e4fde8f7f3b4db2bc42 (patch) | |
| tree | d84b6f956fd43d8a3bb2dff3a1bde9e27dcc1cc2 | |
| parent | Style improvements who dis (diff) | |
| download | disml-6163027a715b31d87e1f8e4fde8f7f3b4db2bc42.tar.xz disml-6163027a715b31d87e1f8e4fde8f7f3b4db2bc42.zip | |
Initial Lwt changes. Successfully compiles
56 files changed, 1009 insertions, 1013 deletions
@@ -1,8 +1,9 @@ -open Async
-open Core
+open Lwt.Infix
open Disml
open Models
+module String = Base.String
+
(* Define a function to handle message_create *)
let check_command (message:Message.t) =
(* Simple example of command parsing. *)
@@ -16,37 +17,39 @@ let check_command (message:Message.t) = | "!embed" -> Commands.embed message rest
| "!status" -> Commands.status message rest
| "!echo" -> Commands.echo message rest
- | "!cache" -> Commands.cache message rest
+ (* | "!cache" -> Commands.cache message rest *)
| "!shutdown" -> Commands.shutdown message rest
| "!rgm" -> Commands.request_members message rest
- | "!new" -> Commands.new_guild message rest
- | "!delall" -> Commands.delete_guilds message rest
- | "!roletest" -> Commands.role_test message rest
- | "!perms" -> Commands.check_permissions message rest
- | _ -> () (* Fallback case, no matched command. *)
+ (* | "!new" -> Commands.new_guild message rest *)
+ (* | "!delall" -> Commands.delete_guilds message rest *)
+ (* | "!roletest" -> Commands.role_test message rest *)
+ (* | "!perms" -> Commands.check_permissions message rest *)
+ | _ -> Lwt.return_unit (* Fallback case, no matched command. *)
(* Example logs setup *)
let setup_logger () =
- Logs.set_reporter (Logs_fmt.reporter ());
- Logs.set_level ~all:true (Some Logs.Debug)
+ let open Logs in
+ set_reporter (format_reporter ());
+ set_level (Some Info)
let main () =
- setup_logger ();
(* Register some event handlers *)
Client.message_create := check_command;
- Client.ready := (fun ready -> Logs.info (fun m -> m "Logged in as %s" (User.tag ready.user)));
- Client.guild_create := (fun guild -> Logs.info (fun m -> m "Joined guild %s" guild.name));
- Client.guild_delete := (fun {id;_} -> let `Guild_id id = id in Logs.info (fun m -> m "Left guild %d" id));
+ Client.ready := (fun ready -> Logs_lwt.info (fun m -> m "Logged in as %s" (User.tag ready.user)));
+ Client.guild_create := (fun guild -> Logs_lwt.info (fun m -> m "Joined guild %s" guild.name));
+ Client.guild_delete := (fun {id;_} -> let `Guild_id id = id in Logs_lwt.info (fun m -> m "Left guild %d" id));
(* Pull token from env var. It is not recommended to hardcode your token. *)
- let token = match Sys.getenv "DISCORD_TOKEN" with
+ let token = match Stdlib.Sys.getenv_opt "DISCORD_TOKEN" with
| Some t -> t
| None -> failwith "No token in env"
in
(* Start client. *)
Client.start ~large:250 ~compress:true token
(* Fill that ivar once its done *)
- >>> Ivar.fill Commands.client
+ >|= Lwt.wakeup_later Commands.r_client >>= fun _ ->
+ fst (Lwt.wait ())
(* Lastly, we have to register this to the Async Scheduler for anything to work *)
let _ =
- Scheduler.go_main ~main ()
+ setup_logger ();
+ Lwt_main.run @@ main ()
diff --git a/bin/commands.ml b/bin/commands.ml index afdc40a..a278b5d 100644 --- a/bin/commands.ml +++ b/bin/commands.ml @@ -1,34 +1,39 @@ -open Async -open Core +open Lwt.Infix open Disml open Models +module Option = Base.Option +module Error = Base.Error +module List = Base.List +module Int = Base.Int + (* Client object will be stored here after creation. *) -let client = Ivar.create () +let client, r_client = Lwt.wait () (* Example ping command with REST round trip time edited into the response. *) let ping message _args = - Message.reply message "Pong!" >>> function - | Ok message -> - let diff = Time.diff (Time.now ()) (Time.of_string message.timestamp) in - Message.set_content message (Printf.sprintf "Pong! `%d ms`" (Time.Span.to_ms diff |> Float.abs |> Float.to_int)) >>> ignore - | Error e -> Error.raise e + Message.reply message "Pong!" >>= function + | Ok _message -> Lwt.return_unit + (* let diff = Time.diff (Time.now ()) (Time.of_string message.timestamp) in + Message.set_content message (Printf.sprintf "Pong! `%d ms`" (Time.Span.to_ms diff |> Float.abs |> Float.to_int)) *) + | Error e -> Error.(of_string e |> raise) (* Send a list of consecutive integers of N size with 1 message per list item. *) let spam message args = let count = Option.((List.hd args >>| Int.of_string) |> value ~default:0) in List.range 0 count - |> List.iter ~f:(fun i -> Message.reply message (string_of_int i) >>> ignore) + |> List.iter ~f:(fun i -> Lwt.async (fun () -> Message.reply message (string_of_int i))) + |> Lwt.return (* Send a list of consecutive integers of N size in a single message. *) let list message args = let count = Option.((List.hd args >>| Int.of_string) |> value ~default:0) in let list = List.range 0 count |> List.sexp_of_t Int.sexp_of_t - |> Sexp.to_string_hum in - Message.reply message list >>> function + |> Sexplib.Sexp.to_string_hum in + Message.reply message list >|= function | Ok msg -> print_endline msg.content - | Error err -> print_endline (Error.to_string_hum err) + | Error err -> print_endline err (* Example of setting pretty much everything in an embed using the Embed module builders *) let embed message _args = @@ -37,7 +42,7 @@ let embed message _args = |> title "Foo" |> description "Bar" |> url "https://gitlab.com/Mishio595/disml" - |> timestamp Time.(now () |> to_string_iso8601_basic ~zone:Time.Zone.utc) + (* |> timestamp Time.(now () |> to_string_iso8601_basic ~zone:Time.Zone.utc) *) |> colour 0xff |> footer (fun f -> footer_text "boop" f) |> image image_url @@ -50,42 +55,42 @@ let embed message _args = |> field ("field 2", "test", true) |> field ("field 1", "test", true) ) in - Message.reply_with ~embed message >>> ignore + Message.reply_with ~embed message >|= ignore (* Set the status of all shards to a given string. *) let status message args = let name = List.fold ~init:"" ~f:(fun a v -> a ^ " " ^ v) args in - Ivar.read client >>> fun client -> + client >>= fun client -> Client.set_status ~name client - >>> fun _ -> - Message.reply message "Updated status" >>> ignore + >>= fun _ -> + Message.reply message "Updated status" >|= ignore (* Fetches a message by ID in the current channel, defaulting to the sent message, and prints in s-expr form. *) let echo (message:Message.t) args = let `Message_id id = message.id in let id = Option.((List.hd args >>| Int.of_string) |> value ~default:id) in - Channel_id.get_message ~id message.channel_id >>> function + Channel_id.get_message ~id message.channel_id >>= function | Ok msg -> - let str = Message.sexp_of_t msg |> Sexp.to_string_hum in - Message.reply message (Printf.sprintf "```lisp\n%s```" str) >>> ignore - | _ -> () + let str = Message.sexp_of_t msg |> Sexplib.Sexp.to_string_hum in + Message.reply message (Printf.sprintf "```lisp\n%s```" str) >|= ignore + | _ -> Lwt.return_unit (* Output cache counts as a a basic embed. *) -let cache message _args = +(* let cache message _args = let module C = Cache.ChannelMap in let module G = Cache.GuildMap in let module U = Cache.UserMap in let cache = Mvar.peek_exn Cache.cache in - let gc = G.length cache.guilds in - let ug = G.length cache.unavailable_guilds in - let tc = C.length cache.text_channels in - let vc = C.length cache.voice_channels in - let cs = C.length cache.categories in - let gr = C.length cache.groups in - let pr = C.length cache.private_channels in - let uc = U.length cache.users in - let pre = U.length cache.presences in - let user = Option.(value ~default:"None" (cache.user >>| User.tag)) in + let gc = G.cardinal cache.guilds in + let ug = G.cardinal cache.unavailable_guilds in + let tc = C.cardinal cache.text_channels in + let vc = C.cardinal cache.voice_channels in + let cs = C.cardinal cache.categories in + let gr = C.cardinal cache.groups in + let pr = C.cardinal cache.private_channels in + let uc = U.cardinal cache.users in + let pre = U.cardinal cache.presences in + let user = Option.(value ~default:"None" (map cache.user ~f:User.tag)) in let embed = Embed.(default |> description (Printf.sprintf "Guilds: %d\nUnavailable Guilds: %d\n\ @@ -94,32 +99,33 @@ let cache message _args = Private Channels: %d\nUsers: %d\n\ Presences: %d\nCurrent User: %s" gc ug tc vc cs gr pr uc pre user)) in - Message.reply_with ~embed message >>> ignore + Message.reply_with ~embed message >|= ignore *) (* Issue a shutdown to all shards, then exits the process. *) let shutdown (message:Message.t) _args = if message.author.id = `User_id 242675474927583232 then - Ivar.read client >>= Client.shutdown_all ~restart:false >>> fun _ -> - exit 0 + client >>= Client.shutdown_all ~restart:false >|= fun _ -> + exit 0 + else Lwt.return_unit (* Request guild members to be sent over the gateway for the guild the command is run in. This will cause multiple GUILD_MEMBERS_CHUNK events. *) let request_members (message:Message.t) _args = - Ivar.read client >>> fun client -> + client >>= fun client -> match message.guild_id with - | Some guild -> Client.request_guild_members ~guild client >>> ignore - | None -> () + | Some guild -> Client.request_guild_members ~guild client >|= ignore + | None -> Lwt.return_unit (* Creates a guild named testing or what the user provided *) -let new_guild message args = +(* let new_guild message args = let name = List.fold ~init:"" ~f:(fun a v -> a ^ " " ^ v) args in let name = if String.length name = 0 then "Testing" else name in Guild.create [ "name", `String name ] >>= begin function | Ok g -> Message.reply message (Printf.sprintf "Created guild %s" g.name) - | Error e -> Message.reply message (Printf.sprintf "Failed to create guild. Error: %s" (Error.to_string_hum e)) - end >>> ignore + | Error e -> Message.reply message (Printf.sprintf "Failed to create guild. Error: %s" e) + end *) (* Deletes all guilds made by the bot *) -let delete_guilds message _args = +(* let delete_guilds message _args = let cache = Mvar.peek_exn Cache.cache in let uid = match cache.user with | Some u -> u.id @@ -131,9 +137,9 @@ let delete_guilds message _args = | Ok () -> res := Printf.sprintf "%s\nDeleted %s" !res g.name | Error _ -> ()) |> to_alist) |> List.map ~f:(snd) in Deferred.all all >>= (fun _ -> - Message.reply message !res) >>> ignore + Message.reply message !res) >|= ignore *) -let role_test (message:Message.t) args = +(* let role_test (message:Message.t) args = let exception Member_not_found in let cache = Mvar.peek_exn Cache.cache in let name = List.fold ~init:"" ~f:(fun a v -> a ^ " " ^ v) args in @@ -176,10 +182,10 @@ let role_test (message:Message.t) args = with | Member_not_found -> Message.reply message "Error: Member not found" | exn -> Message.reply message (Printf.sprintf "Error: %s" Error.(of_exn exn |> to_string_hum)) - end >>> ignore - | None -> () + end >|= ignore + | None -> () *) -let check_permissions (message:Message.t) _args = +(* let check_permissions (message:Message.t) _args = let cache = Mvar.peek_exn Cache.cache in let empty = Permissions.empty in let permissions = match message.guild_id, message.member with @@ -194,7 +200,7 @@ let check_permissions (message:Message.t) _args = | _ -> empty in let allow, deny = match message.member with | Some m -> - begin match Cache.text_channel cache message.channel_id with + begin match Cache.text_channel message.channel_id cache with | Some c -> List.fold c.permission_overwrites ~init:(empty, empty) ~f:(fun (a,d) {allow; deny; id; kind} -> let `User_id uid = message.author.id in @@ -207,10 +213,10 @@ let check_permissions (message:Message.t) _args = | None -> empty, empty in let g_perms = Permissions.elements permissions |> List.sexp_of_t Permissions.sexp_of_elt - |> Sexp.to_string_hum in + |> Sexplib.Sexp.to_string_hum in let c_perms = Permissions.(union permissions allow |> diff deny |> elements) |> List.sexp_of_t Permissions.sexp_of_elt - |> Sexp.to_string_hum in - Message.reply message (Printf.sprintf "Global Permissions: %s\nChannel Permissions: %s" g_perms c_perms) >>> ignore
\ No newline at end of file + |> Sexplib.Sexp.to_string_hum in + Message.reply message (Printf.sprintf "Global Permissions: %s\nChannel Permissions: %s" g_perms c_perms) >|= ignore *)
\ No newline at end of file @@ -1,5 +1,5 @@ (executable (name bot) (modules bot commands) - (libraries core async_ssl disml) + (libraries lwt disml base) )
\ No newline at end of file diff --git a/lib/cache.ml b/lib/cache.ml index 96ca42a..753ec73 100644 --- a/lib/cache.ml +++ b/lib/cache.ml @@ -1,6 +1,3 @@ -open Core
-open Async
-
module ChannelMap = Map.Make(Channel_id_t)
module GuildMap = Map.Make(Guild_id_t)
module UserMap = Map.Make(User_id_t)
@@ -32,38 +29,35 @@ let create () = ; users = UserMap.empty
}
-let cache =
- let m = Mvar.create () in
- Mvar.set m (create ());
- m
+let cache = Lwt_mvar.create (create ())
-let guild cache = GuildMap.find cache.guilds
+let guild k cache = GuildMap.find_opt k cache.guilds
-let text_channel cache = ChannelMap.find cache.text_channels
+let text_channel k cache = ChannelMap.find_opt k cache.text_channels
-let voice_channel cache = ChannelMap.find cache.voice_channels
+let voice_channel k cache = ChannelMap.find_opt k cache.voice_channels
-let category cache = ChannelMap.find cache.categories
+let category k cache = ChannelMap.find_opt k cache.categories
-let dm cache = ChannelMap.find cache.private_channels
+let dm k cache = ChannelMap.find_opt k cache.private_channels
-let group cache = ChannelMap.find cache.groups
+let group k cache = ChannelMap.find_opt k cache.groups
-let channel cache id =
- let check = ChannelMap.find in
- match check cache.text_channels id with
+let channel id cache : Channel_t.t option =
+ let check = ChannelMap.find_opt in
+ match check id cache.text_channels with
| Some c -> Some (`GuildText c)
| None -> (
- match check cache.voice_channels id with
+ match check id cache.voice_channels with
| Some c -> Some (`GuildVoice c)
| None -> (
- match check cache.categories id with
+ match check id cache.categories with
| Some c -> Some (`Category c)
| None -> (
- match check cache.private_channels id with
+ match check id cache.private_channels with
| Some c -> Some (`Private c)
| None -> (
- match check cache.groups id with
+ match check id cache.groups with
| Some c -> Some (`Group c)
| None -> None
))))
\ No newline at end of file diff --git a/lib/cache.mli b/lib/cache.mli index 24a8a1b..7a76b57 100644 --- a/lib/cache.mli +++ b/lib/cache.mli @@ -1,6 +1,3 @@ -open Async
-open Core
-
(** Represents a Map of {!Channel_id.t} keys. *)
module ChannelMap : module type of Map.Make(Channel_id_t)
@@ -28,7 +25,7 @@ type t = }
(** A {{!t}cache} wrapped in an {{!Async.Mvar.Read_write.t}Mvar}. *)
-val cache : t Mvar.Read_write.t
+val cache : t Lwt_mvar.t
(** Creates a new, empty cache. *)
val create :
@@ -38,42 +35,42 @@ val create : (** Equivalent to {!GuildMap.find} on cache.guilds. *)
val guild :
- t ->
Guild_id_t.t ->
+ t ->
Guild_t.t option
(** Equivalent to {!ChannelMap.find} on cache.text_channels. *)
val text_channel :
- t ->
Channel_id_t.t ->
+ t ->
Channel_t.guild_text option
(** Equivalent to {!ChannelMap.find} on cache.voice_channels. *)
val voice_channel :
- t ->
Channel_id_t.t ->
+ t ->
Channel_t.guild_voice option
(** Equivalent to {!ChannelMap.find} on cache.categories. *)
val category :
- t ->
Channel_id_t.t ->
+ t ->
Channel_t.category option
(** Equivalent to {!ChannelMap.find} on cache.private_channels. *)
val dm :
- t ->
Channel_id_t.t ->
+ t ->
Channel_t.dm option
(** Equivalent to {!ChannelMap.find} on cache.groups. *)
val group :
- t ->
Channel_id_t.t ->
+ t ->
Channel_t.group option
(** Helper method that scans all channel stores and returns a {!Channel.t} holding the channel. *)
val channel :
- t ->
Channel_id_t.t ->
+ t ->
Channel_t.t option
\ No newline at end of file diff --git a/lib/client.ml b/lib/client.ml index cf7bd77..50966e7 100644 --- a/lib/client.ml +++ b/lib/client.ml @@ -1,4 +1,4 @@ -open Async
+open Lwt.Infix
include Dispatch
type t =
@@ -8,7 +8,7 @@ type t = let start ?count ?compress ?(large=250) token =
Client_options.token := token;
Sharder.start ?count ?compress ~large_threshold:large ()
- >>| fun sharder ->
+ >|= fun sharder ->
{ sharder; }
let set_status ?status ?kind ?name ?since ?url client =
diff --git a/lib/client.mli b/lib/client.mli index 6d7c931..a9ca914 100644 --- a/lib/client.mli +++ b/lib/client.mli @@ -1,5 +1,3 @@ -open Async
-
include module type of Dispatch
(** Type of the Client, it isn't recommended to access the fields directly. *)
@@ -31,7 +29,7 @@ val start : ?compress:bool ->
?large:int ->
string ->
- t Deferred.t
+ t Lwt.t
(** Same as {!Sharder.set_status} where [client.sharder] is passed. *)
val set_status :
@@ -41,7 +39,7 @@ val set_status : ?since:int ->
?url:string ->
t ->
- Sharder.Shard.shard list Deferred.t
+ unit Lwt.t
(** Same as {!Sharder.request_guild_members} where [client.sharder] is passed. *)
val request_guild_members :
@@ -49,10 +47,10 @@ val request_guild_members : ?query:string ->
?limit:int ->
t ->
- Sharder.Shard.shard list Deferred.t
+ unit Lwt.t
(** Same as {!Sharder.shutdown_all} where [client.sharder] is passed. *)
val shutdown_all :
?restart:bool ->
t ->
- unit list Deferred.t
+ unit Lwt.t
@@ -22,7 +22,7 @@ event_models
cache client client_options disml dispatch endpoints event http opcode rl sharder
)
- (libraries checkseum.ocaml core async_ssl cohttp-async decompress logs yojson websocket-async ppx_deriving_yojson.runtime bitmasks)
+ (libraries str checkseum.ocaml base lwt_ssl cohttp-lwt decompress yojson websocket-lwt ppx_deriving_yojson.runtime bitmasks)
(preprocess (pps ppx_sexp_conv ppx_deriving_yojson)))
(include_subdirs unqualified)
diff --git a/lib/gateway/dispatch.ml b/lib/gateway/dispatch.ml index 6776ff2..593896c 100644 --- a/lib/gateway/dispatch.ml +++ b/lib/gateway/dispatch.ml @@ -1,37 +1,36 @@ -open Core
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.t) -> ()) *)
-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.t) -> ()) *)
-(* let voice_server_update = ref (fun (_:Yojson.Safe.t) -> ()) *)
-let webhook_update = ref (fun (_:WebhookUpdate.t) -> ())
-let unknown = ref (fun (_:Unknown.t) -> ())
\ No newline at end of file +let ready = ref (fun (_:Ready.t) -> Lwt.return_unit)
+let resumed = ref (fun (_:Resumed.t) -> Lwt.return_unit)
+let channel_create = ref (fun (_:ChannelCreate.t) -> Lwt.return_unit)
+let channel_update = ref (fun (_:ChannelUpdate.t) -> Lwt.return_unit)
+let channel_delete = ref (fun (_:ChannelDelete.t) -> Lwt.return_unit)
+let channel_pins_update = ref (fun (_:ChannelPinsUpdate.t) -> Lwt.return_unit)
+let guild_create = ref (fun (_:GuildCreate.t) -> Lwt.return_unit)
+let guild_update = ref (fun (_:GuildUpdate.t) -> Lwt.return_unit)
+let guild_delete = ref (fun (_:GuildDelete.t) -> Lwt.return_unit)
+let member_ban = ref (fun (_:GuildBanAdd.t) -> Lwt.return_unit)
+let member_unban = ref (fun (_:GuildBanRemove.t) -> Lwt.return_unit)
+let guild_emojis_update = ref (fun (_:GuildEmojisUpdate.t) -> Lwt.return_unit)
+(* let integrations_update = ref (fun (_:Yojson.Safe.t) -> Lwt.return_unit) *)
+let member_join = ref (fun (_:GuildMemberAdd.t) -> Lwt.return_unit)
+let member_leave = ref (fun (_:GuildMemberRemove.t) -> Lwt.return_unit)
+let member_update = ref (fun (_:GuildMemberUpdate.t) -> Lwt.return_unit)
+let members_chunk = ref (fun (_:GuildMembersChunk.t) -> Lwt.return_unit)
+let role_create = ref (fun (_:GuildRoleCreate.t) -> Lwt.return_unit)
+let role_update = ref (fun (_:GuildRoleUpdate.t) -> Lwt.return_unit)
+let role_delete = ref (fun (_:GuildRoleDelete.t) -> Lwt.return_unit)
+let message_create = ref (fun (_:MessageCreate.t) -> Lwt.return_unit)
+let message_update = ref (fun (_:MessageUpdate.t) -> Lwt.return_unit)
+let message_delete = ref (fun (_:MessageDelete.t) -> Lwt.return_unit)
+let message_delete_bulk = ref (fun (_:MessageDeleteBulk.t) -> Lwt.return_unit)
+let reaction_add = ref (fun (_:ReactionAdd.t) -> Lwt.return_unit)
+let reaction_remove = ref (fun (_:ReactionRemove.t) -> Lwt.return_unit)
+let reaction_remove_all = ref (fun (_:ReactionRemoveAll.t) -> Lwt.return_unit)
+let presence_update = ref (fun (_:PresenceUpdate.t) -> Lwt.return_unit)
+let typing_start = ref (fun (_:TypingStart.t) -> Lwt.return_unit)
+let user_update = ref (fun (_:UserUpdate.t) -> Lwt.return_unit)
+(* let voice_state_update = ref (fun (_:Yojson.Safe.t) -> Lwt.return_unit) *)
+(* let voice_server_update = ref (fun (_:Yojson.Safe.t) -> Lwt.return_unit) *)
+let webhook_update = ref (fun (_:WebhookUpdate.t) -> Lwt.return_unit)
+let unknown = ref (fun (_:Unknown.t) -> Lwt.return_unit)
\ No newline at end of file diff --git a/lib/gateway/dispatch.mli b/lib/gateway/dispatch.mli index 89905a6..1ec1271 100644 --- a/lib/gateway/dispatch.mli +++ b/lib/gateway/dispatch.mli @@ -20,101 +20,101 @@ Client.message_create := check_command 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 : (Ready.t -> unit) ref
+val ready : (Ready.t -> unit Lwt.t) ref
(** Dispatched when successfully reconnecting to the gateway. *)
-val resumed : (Resumed.t -> unit) ref
+val resumed : (Resumed.t -> unit Lwt.t) ref
(** Dispatched when a channel is created which is visible to the bot. *)
-val channel_create : (ChannelCreate.t -> unit) ref
+val channel_create : (ChannelCreate.t -> unit Lwt.t) ref
(** Dispatched when a channel visible to the bot is changed. *)
-val channel_update : (ChannelUpdate.t -> unit) ref
+val channel_update : (ChannelUpdate.t -> unit Lwt.t) ref
(** Dispatched when a channel visible to the bot is deleted. *)
-val channel_delete : (ChannelDelete.t -> unit) ref
+val channel_delete : (ChannelDelete.t -> unit Lwt.t) ref
(** Dispatched when messages are pinned or unpinned from a a channel. *)
-val channel_pins_update : (ChannelPinsUpdate.t -> unit) ref
+val channel_pins_update : (ChannelPinsUpdate.t -> unit Lwt.t) ref
(** Dispatched when the bot joins a guild, and during startup. *)
-val guild_create : (GuildCreate.t -> unit) ref
+val guild_create : (GuildCreate.t -> unit Lwt.t) ref
(** Dispatched when a guild the bot is in is edited. *)
-val guild_update : (GuildUpdate.t -> unit) ref
+val guild_update : (GuildUpdate.t -> unit Lwt.t) ref
(** Dispatched when the bot is removed from a guild. *)
-val guild_delete : (GuildDelete.t -> unit) ref
+val guild_delete : (GuildDelete.t -> unit Lwt.t) ref
(** Dispatched when a member is banned. *)
-val member_ban : (GuildBanAdd.t -> unit) ref
+val member_ban : (GuildBanAdd.t -> unit Lwt.t) ref
(** Dispatched when a member is unbanned. *)
-val member_unban : (GuildBanRemove.t -> unit) ref
+val member_unban : (GuildBanRemove.t -> unit Lwt.t) ref
(** Dispatched when emojis are added or removed from a guild. *)
-val guild_emojis_update : (GuildEmojisUpdate.t -> unit) ref
+val guild_emojis_update : (GuildEmojisUpdate.t -> unit Lwt.t) ref
(** Dispatched when a guild's integrations are updated. *)
-(* val integrations_update : (Yojson.Safe.t -> unit) ref *)
+(* val integrations_update : (Yojson.Safe.t -> unit Lwt.t) ref *)
(** Dispatched when a member joins a guild. *)
-val member_join : (GuildMemberAdd.t -> unit) ref
+val member_join : (GuildMemberAdd.t -> unit Lwt.t) ref
(** Dispatched when a member leaves a guild. Is Dispatched alongside {!Client.member_ban} when a user is banned. *)
-val member_leave : (GuildMemberRemove.t -> unit) ref
+val member_leave : (GuildMemberRemove.t -> unit Lwt.t) ref
(** Dispatched when a member object is updated. *)
-val member_update : (GuildMemberUpdate.t -> unit) ref
+val member_update : (GuildMemberUpdate.t -> unit Lwt.t) ref
(** Dispatched when requesting guild members through {!Client.request_guild_members} *)
-val members_chunk : (GuildMembersChunk.t -> unit) ref
+val members_chunk : (GuildMembersChunk.t -> unit Lwt.t) ref
(** Dispatched when a role is created. *)
-val role_create : (GuildRoleCreate.t -> unit) ref
+val role_create : (GuildRoleCreate.t -> unit Lwt.t) ref
(** Dispatched when a role is edited. *)
-val role_update : (GuildRoleUpdate.t -> unit) ref
+val role_update : (GuildRoleUpdate.t -> unit Lwt.t) ref
(** Dispatched when a role is deleted. *)
-val role_delete : (GuildRoleDelete.t -> unit) ref
+val role_delete : (GuildRoleDelete.t -> unit Lwt.t) ref
(** Dispatched when a message is sent. *)
-val message_create : (MessageCreate.t -> unit) ref
+val message_create : (MessageCreate.t -> unit Lwt.t) ref
(** Dispatched when a message is edited. This does not necessarily mean the content changed. *)
-val message_update : (MessageUpdate.t -> unit) ref
+val message_update : (MessageUpdate.t -> unit Lwt.t) ref
(** Dispatched when a message is deleted. *)
-val message_delete : (MessageDelete.t -> unit) ref
+val message_delete : (MessageDelete.t -> unit Lwt.t) ref
(** Dispatched when messages are bulk deleted. *)
-val message_delete_bulk : (MessageDeleteBulk.t -> unit) ref
+val message_delete_bulk : (MessageDeleteBulk.t -> unit Lwt.t) ref
(** Dispatched when a rection is added to a message. *)
-val reaction_add : (ReactionAdd.t -> unit) ref
+val reaction_add : (ReactionAdd.t -> unit Lwt.t) ref
(** Dispatched when a reaction is removed from a message. *)
-val reaction_remove : (ReactionRemove.t -> unit) ref
+val reaction_remove : (ReactionRemove.t -> unit Lwt.t) ref
(** Dispatched when all reactions are cleared from a message. *)
-val reaction_remove_all : (ReactionRemoveAll.t -> unit) ref
+val reaction_remove_all : (ReactionRemoveAll.t -> unit Lwt.t) ref
(** Dispatched when a user updates their presence. *)
-val presence_update : (PresenceUpdate.t -> unit) ref
+val presence_update : (PresenceUpdate.t -> unit Lwt.t) ref
(** Dispatched when a typing indicator is displayed. *)
-val typing_start : (TypingStart.t -> unit) ref
+val typing_start : (TypingStart.t -> unit Lwt.t) ref
(** Dispatched when the current user is updated. You most likely want {!Client.member_update} or {!Client.presence_update} instead. *)
-val user_update : (UserUpdate.t -> unit) ref
+val user_update : (UserUpdate.t -> unit Lwt.t) ref
(** Dispatched when a webhook is updated. *)
-val webhook_update : (WebhookUpdate.t -> unit) ref
+val webhook_update : (WebhookUpdate.t -> unit Lwt.t) ref
(** Dispatched as a fallback for unknown events. *)
-val unknown : (Unknown.t -> unit) ref
+val unknown : (Unknown.t -> unit Lwt.t) ref
(**/**)
-(* val voice_state_update : (Yojson.Safe.t -> unit) ref *)
-(* val voice_server_update : (Yojson.Safe.t -> unit) ref *)
+(* val voice_state_update : (Yojson.Safe.t -> unit Lwt.t) ref *)
+(* val voice_server_update : (Yojson.Safe.t -> unit Lwt.t) ref *)
diff --git a/lib/gateway/event.ml b/lib/gateway/event.ml index 88dd50d..af9861d 100644 --- a/lib/gateway/event.ml +++ b/lib/gateway/event.ml @@ -1,5 +1,4 @@ -open Async
-open Core
+open Lwt.Infix
open Event_models
type t =
@@ -74,103 +73,137 @@ let event_of_yojson ~contents = function | "WEBHOOK_UPDATE" -> WEBHOOK_UPDATE WebhookUpdate.(deserialize contents)
| s -> UNKNOWN Unknown.(deserialize s contents)
-let dispatch ev =
+let dispatch cache ev =
match ev with
| READY d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> Ready.update_cache cache d);
- !Dispatch.ready d
+ let cache = Ready.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.ready d);
+ cache
| RESUMED d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> Resumed.update_cache cache d);
- !Dispatch.resumed d
+ let cache = Resumed.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.resumed d);
+ cache
| CHANNEL_CREATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> ChannelCreate.update_cache cache d);
- !Dispatch.channel_create d
+ let cache = ChannelCreate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.channel_create d);
+ cache
| CHANNEL_UPDATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> ChannelUpdate.update_cache cache d);
- !Dispatch.channel_update d
+ let cache = ChannelDelete.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.channel_update d);
+ cache
| CHANNEL_DELETE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> ChannelDelete.update_cache cache d);
- !Dispatch.channel_delete d
+ let cache = ChannelDelete.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.channel_delete d);
+ cache
| CHANNEL_PINS_UPDATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> ChannelPinsUpdate.update_cache cache d);
- !Dispatch.channel_pins_update d
+ let cache = ChannelPinsUpdate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.channel_pins_update d);
+ cache
| GUILD_CREATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildCreate.update_cache cache d);
- !Dispatch.guild_create d
+ let cache = GuildCreate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.guild_create d);
+ cache
| GUILD_UPDATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildUpdate.update_cache cache d);
- !Dispatch.guild_update d
+ let cache = GuildUpdate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.guild_update d);
+ cache
| GUILD_DELETE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildDelete.update_cache cache d);
- !Dispatch.guild_delete d
+ let cache = GuildDelete.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.guild_delete d);
+ cache
| GUILD_BAN_ADD d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildBanAdd.update_cache cache d);
- !Dispatch.member_ban d
+ let cache = GuildBanAdd.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.member_ban d);
+ cache
| GUILD_BAN_REMOVE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildBanRemove.update_cache cache d);
- !Dispatch.member_unban d
+ let cache = GuildBanRemove.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.member_unban d);
+ cache
| GUILD_EMOJIS_UPDATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildEmojisUpdate.update_cache cache d);
- !Dispatch.guild_emojis_update d
+ let cache = GuildEmojisUpdate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.guild_emojis_update d);
+ cache
(* | GUILD_INTEGRATIONS_UPDATE d -> !Dispatch.integrations_update d *)
| GUILD_MEMBER_ADD d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildMemberAdd.update_cache cache d);
- !Dispatch.member_join d
+ let cache = GuildMemberAdd.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.member_join d);
+ cache
| GUILD_MEMBER_REMOVE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildMemberRemove.update_cache cache d);
- !Dispatch.member_leave d
+ let cache = GuildMemberRemove.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.member_leave d);
+ cache
| GUILD_MEMBER_UPDATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildMemberUpdate.update_cache cache d);
- !Dispatch.member_update d
+ let cache = GuildMemberUpdate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.member_update d);
+ cache
| GUILD_MEMBERS_CHUNK d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildMembersChunk.update_cache cache d);
- !Dispatch.members_chunk d
+ let cache = GuildMembersChunk.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.members_chunk d);
+ cache
| GUILD_ROLE_CREATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildRoleCreate.update_cache cache d);
- !Dispatch.role_create d
+ let cache = GuildRoleCreate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.role_create d);
+ cache
| GUILD_ROLE_UPDATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildRoleUpdate.update_cache cache d);
- !Dispatch.role_update d
+ let cache = GuildRoleUpdate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.role_update d);
+ cache
| GUILD_ROLE_DELETE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> GuildRoleDelete.update_cache cache d);
- !Dispatch.role_delete d
+ let cache = GuildRoleDelete.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.role_delete d);
+ cache
| MESSAGE_CREATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> MessageCreate.update_cache cache d);
- !Dispatch.message_create d
+ let cache = MessageCreate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.message_create d);
+ cache
| MESSAGE_UPDATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> MessageUpdate.update_cache cache d);
- !Dispatch.message_update d
+ let cache = MessageUpdate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.message_update d);
+ cache
| MESSAGE_DELETE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> MessageDelete.update_cache cache d);
- !Dispatch.message_delete d
+ let cache = MessageDelete.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.message_delete d);
+ cache
| MESSAGE_DELETE_BULK d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> MessageDeleteBulk.update_cache cache d);
- !Dispatch.message_delete_bulk d
+ let cache = MessageDeleteBulk.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.message_delete_bulk d);
+ cache
| REACTION_ADD d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> ReactionAdd.update_cache cache d);
- !Dispatch.reaction_add d
+ let cache = ReactionAdd.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.reaction_add d);
+ cache
| REACTION_REMOVE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> ReactionRemove.update_cache cache d);
- !Dispatch.reaction_remove d
+ let cache = ReactionRemove.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.reaction_remove d);
+ cache
| REACTION_REMOVE_ALL d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> ReactionRemoveAll.update_cache cache d);
- !Dispatch.reaction_remove_all d
+ let cache = ReactionRemoveAll.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.reaction_remove_all d);
+ cache
| PRESENCE_UPDATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> PresenceUpdate.update_cache cache d);
- !Dispatch.presence_update d
+ let cache = PresenceUpdate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.presence_update d);
+ cache
| TYPING_START d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> TypingStart.update_cache cache d);
- !Dispatch.typing_start d
+ let cache = TypingStart.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.typing_start d);
+ cache
| USER_UPDATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> UserUpdate.update_cache cache d);
- !Dispatch.user_update d
+ let cache = UserUpdate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.user_update d);
+ cache
(* | VOICE_STATE_UPDATE d -> !Dispatch.voice_state_update d *)
(* | VOICE_SERVER_UPDATE d -> !Dispatch.voice_server_update d *)
| WEBHOOK_UPDATE d ->
- Mvar.update_exn Cache.cache ~f:(fun cache -> WebhookUpdate.update_cache cache d);
- !Dispatch.webhook_update d
- | UNKNOWN d -> !Dispatch.unknown d
+ let cache = WebhookUpdate.update_cache cache d in
+ Lwt.async (fun () -> !Dispatch.webhook_update d);
+ cache
+ | UNKNOWN d ->
+ Lwt.async (fun () -> !Dispatch.unknown d);
+ cache
let handle_event ~ev contents =
+ Lwt_mvar.take Cache.cache >>= fun cache ->
event_of_yojson ~contents ev
- |> dispatch
\ No newline at end of file + |> dispatch cache
+ |> Lwt_mvar.put Cache.cache
\ No newline at end of file diff --git a/lib/gateway/event.mli b/lib/gateway/event.mli index 4db3c84..1817c52 100644 --- a/lib/gateway/event.mli +++ b/lib/gateway/event.mli @@ -43,7 +43,7 @@ type t = val event_of_yojson : contents:Yojson.Safe.t -> string -> t
(** Sends the event to the registered handler. *)
-val dispatch : t -> unit
+val dispatch : Cache.t -> t -> Cache.t
(** Wrapper to other functions. This is called from the shards. *)
-val handle_event : ev:string -> Yojson.Safe.t -> unit
\ No newline at end of file +val handle_event : ev:string -> Yojson.Safe.t -> unit Lwt.t
\ No newline at end of file diff --git a/lib/gateway/opcode.ml b/lib/gateway/opcode.ml index e2f44aa..f7b8fd7 100644 --- a/lib/gateway/opcode.ml +++ b/lib/gateway/opcode.ml @@ -1,17 +1,16 @@ -open Core
-
type t =
- | DISPATCH
- | HEARTBEAT
- | IDENTIFY
- | STATUS_UPDATE
- | VOICE_STATE_UPDATE
- | RESUME
- | RECONNECT
- | REQUEST_GUILD_MEMBERS
- | INVALID_SESSION
- | HELLO
- | HEARTBEAT_ACK
+| DISPATCH
+| HEARTBEAT
+| IDENTIFY
+| STATUS_UPDATE
+| VOICE_STATE_UPDATE
+| RESUME
+| RECONNECT
+| REQUEST_GUILD_MEMBERS
+| INVALID_SESSION
+| HELLO
+| HEARTBEAT_ACK
+[@@deriving sexp]
exception Invalid_Opcode of int
diff --git a/lib/gateway/opcode.mli b/lib/gateway/opcode.mli index 9fa5b96..5d1a35c 100644 --- a/lib/gateway/opcode.mli +++ b/lib/gateway/opcode.mli @@ -13,6 +13,7 @@ type t = | INVALID_SESSION
| HELLO
| HEARTBEAT_ACK
+[@@deriving sexp]
(** Raised when receiving an invalid opcode. This should never occur. *)
exception Invalid_Opcode of int
diff --git a/lib/gateway/sharder.ml b/lib/gateway/sharder.ml index ba865a9..9c98979 100644 --- a/lib/gateway/sharder.ml +++ b/lib/gateway/sharder.ml @@ -1,7 +1,7 @@ -open Async
-open Core
+open Lwt.Infix
open Decompress
-open Websocket_async
+open Websocket
+open Websocket_lwt
exception Invalid_Payload
exception Failure_to_Establish_Heartbeat
@@ -32,16 +32,17 @@ let decompress src = module Shard = struct
type shard =
{ compress: bool
- ; id: int * int
- ; hb_interval: Time.Span.t Ivar.t
- ; hb_stopper: unit Ivar.t
+ ; hb_interval: int Lwt.t * int Lwt.u
+ ; hb_stopper: unit Lwt.t * unit Lwt.u
+ ; id: int
; large_threshold: int
- ; pipe: Frame.t Pipe.Reader.t * Frame.t Pipe.Writer.t
- ; ready: unit Ivar.t
+ ; ready: unit Lwt.t * unit Lwt.u
+ ; recv: Frame.t Lwt_stream.t
+ ; send: (Frame.t -> unit Lwt.t)
; seq: int
; session: string option
+ ; shard_count: int
; url: string
- ; _internal: Reader.t * Writer.t
}
type 'a t =
@@ -50,44 +51,38 @@ module Shard = struct ; mutable can_resume: bool
}
- let identify_lock = Mvar.create ()
- let _ = Mvar.set identify_lock ()
+ let identify_lock = Lwt_mvar.create ()
- let parse ~compress (frame:[`Ok of Frame.t | `Eof]) =
- match frame with
- | `Ok s -> begin
- let open Frame.Opcode in
- match s.opcode with
- | Text -> `Ok (Yojson.Safe.from_string s.content)
- | Binary ->
- if compress then `Ok (decompress s.content |> Yojson.Safe.from_string)
- else `Error "Failed to decompress"
- | Close -> `Close s
- | op ->
- let op = Frame.Opcode.to_string op in
- `Error ("Unexpected opcode " ^ op)
- end
- | `Eof -> `Eof
+ let parse ~compress (frame:Frame.t) =
+ let open Frame.Opcode in
+ match frame.opcode with
+ | Text -> `Ok (Yojson.Safe.from_string frame.content)
+ | Binary ->
+ if compress then `Ok (decompress frame.content |> Yojson.Safe.from_string)
+ else `Error "Failed to decompress"
+ | Close -> `Close frame
+ | op ->
+ let op = Frame.Opcode.to_string op in
+ `Error ("Unexpected opcode " ^ op)
let push_frame ?payload ~ev shard =
let content = match payload with
| None -> ""
| Some p ->
- Yojson.Safe.to_string @@ `Assoc [
- "op", `Int (Opcode.to_int ev);
- "d", p;
+ Yojson.Safe.to_string @@ `Assoc
+ [ "op", `Int (Opcode.to_int ev)
+ ; "d", p
]
in
- let (_, write) = shard.pipe in
- Pipe.write_if_open write @@ Frame.create ~content ()
- >>| fun () ->
+ Frame.create ~content ()
+ |> shard.send >|= fun () ->
shard
let heartbeat shard =
match shard.seq with
- | 0 -> return shard
+ | 0 -> Lwt.return shard
| i ->
- Logs.debug (fun m -> m "Heartbeating - Shard: [%d, %d] - Seq: %d" (fst shard.id) (snd shard.id) (shard.seq));
+ Logs_lwt.debug (fun m -> m "Heartbeating - Shard: [%d, %d] - Seq: %d" shard.id shard.shard_count shard.seq) >>= fun () ->
push_frame ~payload:(`Int i) ~ev:HEARTBEAT shard
let dispatch ~payload shard =
@@ -96,20 +91,20 @@ module Shard = struct let t = J.(member "t" payload |> to_string) in
let data = J.member "d" payload in
let session = if t = "READY" then begin
- Ivar.fill_if_empty shard.ready ();
- Clock.after (Core.Time.Span.create ~sec:5 ())
- >>> (fun _ -> Mvar.put identify_lock () >>> ignore);
+ Lwt.wakeup_later (snd shard.ready) ();
+ (* TODO figure out action after time in Lwt *)
+ (* Clock.after (Core.Time.Span.create ~sec:5 ())
+ >>> (fun _ -> Lwt_mvar.put identify_lock () >>> ignore); *)
J.(member "session_id" data |> to_string_option)
end else shard.session in
- Event.handle_event ~ev:t data;
- return
+ Event.handle_event ~ev:t data >|= fun () ->
{ shard with seq = seq
; session = session
}
- let set_status ?(status="online") ?(kind=0) ?name ?since ?url shard =
- let since = Option.(since >>| (fun v -> `Int v) |> value ~default:`Null) in
- let url = Option.(url >>| (fun v -> `String v) |> value ~default:`Null) in
+ let set_status ?(status="online") ?(kind=0) ?name ?since ?url shard =
+ let since = Option.(map since ~f:(fun v -> `Int v) |> value ~default:`Null) in
+ let url = Option.(map url ~f:(fun v -> `String v) |> value ~default:`Null) in
let game = match name with
| Some name -> `Assoc
[ "name", `String name
@@ -125,30 +120,30 @@ module Shard = struct ; "game", game
]
in
- Ivar.read shard.ready >>= fun _ ->
+ fst shard.ready >>= fun _ ->
push_frame ~payload ~ev:STATUS_UPDATE shard
let request_guild_members ?(query="") ?(limit=0) ~guild shard =
let payload = `Assoc
- [ "guild_id", `String (Int.to_string guild)
+ [ "guild_id", `String (string_of_int guild)
; "query", `String query
; "limit", `Int limit
]
in
- Ivar.read shard.ready >>= fun _ ->
+ fst shard.ready >>= fun _ ->
push_frame ~payload ~ev:REQUEST_GUILD_MEMBERS shard
let initialize ?data shard =
let module J = Yojson.Safe.Util in
let _ = match data with
- | Some data -> Ivar.fill_if_empty shard.hb_interval (Time.Span.create ~ms:J.(member "heartbeat_interval" data |> to_int) ())
+ | Some data -> Lwt.wakeup_later (snd shard.hb_interval) J.(member "heartbeat_interval" data |> to_int)
| None -> raise Failure_to_Establish_Heartbeat
in
- let shards = [`Int (fst shard.id); `Int (snd shard.id)] in
+ let shards = [`Int shard.id; `Int shard.shard_count] in
match shard.session with
| None -> begin
- Mvar.take identify_lock >>= fun () ->
- Logs.debug (fun m -> m "Identifying shard [%d, %d]" (fst shard.id) (snd shard.id));
+ Lwt_mvar.take identify_lock >>= fun () ->
+ Logs_lwt.debug (fun m -> m "Identifying shard [%d, %d]" shard.id shard.shard_count) >>= fun () ->
let payload = `Assoc
[ "token", `String !Client_options.token
; "properties", `Assoc
@@ -162,7 +157,6 @@ module Shard = struct ]
in
push_frame ~payload ~ev:IDENTIFY shard
- >>| fun s -> s
end
| Some s ->
let payload = `Assoc
@@ -180,117 +174,50 @@ module Shard = struct | DISPATCH -> dispatch ~payload:f shard
| HEARTBEAT -> heartbeat shard
| INVALID_SESSION -> begin
- Logs.err (fun m -> m "Invalid Session on Shard [%d, %d]: %s" (fst shard.id) (snd shard.id) (Yojson.Safe.pretty_to_string f));
- if J.(member "d" f |> to_bool) then
- initialize shard
- else begin
- initialize { shard with session = None; }
- end
+ Logs_lwt.warn (fun m -> m "Invalid Session on Shard [%d, %d]: %s" shard.id shard.shard_count (Yojson.Safe.pretty_to_string f)) >>= fun () ->
+ if J.(member "d" f |> to_bool) then initialize shard
+ else initialize { shard with session = None; }
end
| RECONNECT -> initialize shard
| HELLO -> initialize ~data:(J.member "d" f) shard
- | HEARTBEAT_ACK -> return shard
+ | HEARTBEAT_ACK -> Lwt.return shard
| opcode ->
- Logs.warn (fun m -> m "Invalid Opcode: %s" (Opcode.to_string opcode));
- return shard
-
- let rec make_client
- ~initialized
- ~extra_headers
- ~app_to_ws
- ~ws_to_app
- ~net_to_ws
- ~ws_to_net
- ?(ms=500)
- uri =
- client
- ~initialized
- ~extra_headers
- ~app_to_ws
- ~ws_to_app
- ~net_to_ws
- ~ws_to_net
- uri
- >>> fun res ->
- match res with
- | Ok () -> ()
- | Error _ ->
- let backoff = Time.Span.create ~ms () in
- Clock.after backoff >>> (fun () ->
- make_client
- ~initialized
- ~extra_headers
- ~app_to_ws
- ~ws_to_app
- ~net_to_ws
- ~ws_to_net
- ~ms:(min 60_000 (ms * 2))
- uri)
+ Logs_lwt.warn (fun m -> m "Invalid Opcode: %s" (Opcode.to_string opcode)) >|= fun () ->
+ shard
+ let make_client ?extra_headers uri =
+ let uri = Uri.with_scheme uri (Some "https") in
+ Resolver_lwt.resolve_uri ~uri Resolver_lwt_unix.system >>= fun endp ->
+ Conduit_lwt_unix.(
+ endp_to_client ~ctx:default_ctx endp >>= fun client ->
+ with_connection ?extra_headers ~ctx:default_ctx client uri)
let create ~url ~shards ?(compress=true) ?(large_threshold=100) () =
- let open Core in
- let uri = (url ^ "?v=6&encoding=json") |> Uri.of_string in
+ let uri = Uri.(with_query' (of_string url) ["encoding", "json"; "v", "6"]) in
let extra_headers = Http.Base.process_request_headers () in
- let host = Option.value_exn ~message:"no host in uri" Uri.(host uri) in
- let port =
- match Uri.port uri, Uri_services.tcp_port_of_uri uri with
- | Some p, _ -> p
- | None, Some p -> p
- | _ -> 443 in
- let scheme = Option.value_exn ~message:"no scheme in uri" Uri.(scheme uri) in
- let tcp_fun (net_to_ws, ws_to_net) =
- let (app_to_ws, write) = Pipe.create () in
- let (read, ws_to_app) = Pipe.create () in
- let initialized = Ivar.create () in
- make_client
- ~initialized
- ~extra_headers
- ~app_to_ws
- ~ws_to_app
- ~net_to_ws
- ~ws_to_net
- uri;
- Ivar.read initialized >>| fun () ->
- { pipe = (read, write)
- ; ready = Ivar.create ()
- ; hb_interval = Ivar.create ()
- ; hb_stopper = Ivar.create ()
- ; seq = 0
- ; id = shards
- ; session = None
- ; url
- ; large_threshold
- ; compress
- ; _internal = (net_to_ws, ws_to_net)
- }
- in
- match Unix.getaddrinfo host (string_of_int port) [] with
- | [] -> failwithf "DNS resolution failed for %s" host ()
- | { ai_addr; _ } :: _ ->
- let addr =
- match scheme, ai_addr with
- | _, ADDR_UNIX path -> `Unix_domain_socket path
- | "https", ADDR_INET (h, p)
- | "wss", ADDR_INET (h, p) ->
- let h = Ipaddr_unix.of_inet_addr h in
- `OpenSSL (h, p, Conduit_async.V2.Ssl.Config.create ())
- | _, ADDR_INET (h, p) ->
- let h = Ipaddr_unix.of_inet_addr h in
- `TCP (h, p)
- in
- Conduit_async.V2.connect addr >>= tcp_fun
+ make_client ~extra_headers uri >|= fun (recv, send) ->
+ let recv = mk_frame_stream recv in
+ { compress
+ ; hb_interval = Lwt.wait ()
+ ; hb_stopper = Lwt.wait ()
+ ; id = fst shards
+ ; large_threshold
+ ; ready = Lwt.wait ()
+ ; recv
+ ; send
+ ; seq = 0
+ ; session = None
+ ; shard_count = snd shards
+ ; url
+ }
let shutdown ?(clean=false) ?(restart=true) t =
let _ = clean in
t.can_resume <- restart;
t.stopped <- true;
- Logs.debug (fun m -> m "Performing shutdown. Shard [%d, %d]" (fst t.state.id) (snd t.state.id));
- Pipe.write_if_open (snd t.state.pipe) (Frame.close 1001)
- >>= fun () ->
- Ivar.fill_if_empty t.state.hb_stopper ();
- Pipe.close_read (fst t.state.pipe);
- Writer.close (snd t.state._internal)
+ Logs_lwt.debug (fun m -> m "Performing shutdown. Shard [%d, %d]" t.state.id t.state.shard_count) >>= fun () ->
+ t.state.send (Frame.close 1001) >|= fun () ->
+ Lwt.wakeup_later (snd t.state.hb_stopper) ()
end
type t = { shards: (Shard.shard Shard.t) list }
@@ -300,7 +227,7 @@ let start ?count ?compress ?large_threshold () = Http.get_gateway_bot () >>= fun data ->
let data = match data with
| Ok d -> d
- | Error e -> Error.raise e
+ | Error e -> Base.Error.(of_string e |> raise)
in
let url = J.(member "url" data |> to_string) in
let count = match count with
@@ -311,36 +238,36 @@ let start ?count ?compress ?large_threshold () = Logs.info (fun m -> m "Connecting to %s" url);
let rec ev_loop (t:Shard.shard Shard.t) =
let step (t:Shard.shard Shard.t) =
- Pipe.read (fst t.state.pipe) >>= fun frame ->
+ Lwt_stream.get t.state.recv >>= function None -> Lwt.return t | Some frame ->
begin match Shard.parse ~compress:t.state.compress frame with
| `Ok f ->
- Shard.handle_frame ~f t.state >>| fun s ->
+ Shard.handle_frame ~f t.state >|= fun s ->
t.state <- s
| `Close c ->
- Logs.warn (fun m -> m "Close frame received. %s" (Frame.show c));
+ Logs_lwt.warn (fun m -> m "Close frame received. %s" (Frame.show c)) >>= fun () ->
Shard.shutdown t
| `Error e ->
- Logs.warn (fun m -> m "Websocket soft error: %s" e);
- return ()
+ Logs_lwt.warn (fun m -> m "Websocket soft error: %s" e) >>= fun () ->
+ Lwt.return_unit
| `Eof ->
- Logs.warn (fun m -> m "Websocket closed unexpectedly");
+ Logs_lwt.warn (fun m -> m "Websocket closed unexpectedly") >>= fun () ->
Shard.shutdown t
- end >>| fun () -> t
+ end >|= fun () -> t
in
- if t.stopped then return ()
+ if t.stopped then Lwt.return_unit
else step t >>= ev_loop
in
let rec gen_shards l a =
match l with
- | (id, total) when id >= total -> return a
+ | (id, total) when id >= total -> Lwt.return a
| (id, total) ->
let wrap ?(reuse:Shard.shard Shard.t option) state = match reuse with
| Some t ->
t.state <- state;
t.stopped <- false;
- return t
+ Lwt.return t
| None ->
- return Shard.{ state
+ Lwt.return Shard.{ state
; stopped = false
; can_resume = true
}
@@ -349,34 +276,38 @@ let start ?count ?compress ?large_threshold () = Shard.create ~url ~shards:(id, total) ?compress ?large_threshold ()
in
let rec bind (t:Shard.shard Shard.t) =
- let _ = Ivar.read t.state.hb_interval >>> fun hb ->
- Clock.every'
- ~stop:(Ivar.read t.state.hb_stopper)
- ~continue_on_error:true
- hb (fun () -> Shard.heartbeat t.state >>| ignore) in
- ev_loop t >>> (fun () -> Logs.debug (fun m -> m "Event loop stopped."));
- Pipe.closed (fst t.state.pipe) >>> (fun () -> if t.can_resume then
- create () >>= wrap ~reuse:t >>= bind >>> ignore);
- return t
+ Lwt.async (fun () ->
+ fst t.state.hb_interval >|= fun _hb -> ()
+ (* TODO figure out clocks in Lwt *)
+ );
+ Lwt.async (fun () -> ev_loop t >>= fun () -> Logs_lwt.debug (fun m -> m "Event loop stopped."));
+ (* TODO figure out how to bind to closed websocket *)
+ Lwt.async (fun () -> Lwt_stream.closed t.state.recv >>= fun () ->
+ if t.can_resume then create () >>= wrap ~reuse:t >>= bind >|= ignore
+ else Lwt.return_unit);
+ Lwt.return t
in
create () >>= wrap >>= bind >>= fun t ->
gen_shards (id+1, total) (t :: a)
in
gen_shards shard_list []
- >>| fun shards ->
+ >|= fun shards ->
{ shards }
let set_status ?status ?kind ?name ?since ?url sharder =
- Deferred.all @@ List.map ~f:(fun t ->
- Shard.set_status ?status ?kind ?name ?since ?url t.state
- ) sharder.shards
+ List.map (fun (t:Shard.shard Shard.t) ->
+ Shard.set_status ?status ?kind ?name ?since ?url t.state >|= ignore)
+ sharder.shards
+ |> Lwt.join
let request_guild_members ?query ?limit ~guild sharder =
- Deferred.all @@ List.map ~f:(fun t ->
- Shard.request_guild_members ~guild ?query ?limit t.state
- ) sharder.shards
+ List.map (fun (t:Shard.shard Shard.t) ->
+ Shard.request_guild_members ~guild ?query ?limit t.state >|= ignore)
+ sharder.shards
+ |> Lwt.join
let shutdown_all ?restart sharder =
- Deferred.all @@ List.map ~f:(fun t ->
- Shard.shutdown ~clean:true ?restart t
- ) sharder.shards
+ List.map (fun t ->
+ Shard.shutdown ~clean:true ?restart t)
+ sharder.shards
+ |> Lwt.join
diff --git a/lib/gateway/sharder.mli b/lib/gateway/sharder.mli index 6249d4d..20186f8 100644 --- a/lib/gateway/sharder.mli +++ b/lib/gateway/sharder.mli @@ -1,8 +1,6 @@ (** Internal sharding manager. Most of this is accessed through {!Client}. *)
-open Core
-open Async
-open Websocket_async
+open Websocket
exception Invalid_Payload
exception Failure_to_Establish_Heartbeat
@@ -15,23 +13,24 @@ val start : ?compress:bool ->
?large_threshold:int ->
unit ->
- t Deferred.t
+ t Lwt.t
(** Module representing a single shard. *)
module Shard : sig
(** Representation of the state of a shard. *)
- type shard = {
- compress: bool; (** Whether to compress payloads. *)
- id: int * int; (** A tuple as expected by Discord. First element is the current shard index, second element is the total shard count. *)
- hb_interval: Time.Span.t Ivar.t; (** Time span between heartbeats, wrapped in an Ivar. *)
- hb_stopper: unit Ivar.t; (** Stops the heartbeat sequencer when filled. *)
- large_threshold: int; (** Minimum number of members needed for a guild to be considered large. *)
- pipe: Frame.t Pipe.Reader.t * Frame.t Pipe.Writer.t; (** Raw frame IO pipe used for websocket communications. *)
- ready: unit Ivar.t; (** A simple Ivar indicating if the shard has received READY. *)
- seq: int; (** Current sequence number *)
- session: string option; (** Session id, if one exists. *)
- url: string; (** The websocket URL in use. *)
- _internal: Reader.t * Writer.t;
+ type shard =
+ { compress: bool (** Whether to compress payloads. *)
+ ; hb_interval: int Lwt.t * int Lwt.u (** Time between heartbeats. Not known until HELLO is received. *)
+ ; hb_stopper: unit Lwt.t * unit Lwt.u (** Stops the heartbeat sequencing when filled *)
+ ; id: int (** ID of the current shard. Must be less than shard_count. *)
+ ; large_threshold: int (** Minimum number of members needed for a guild to be considered large. *)
+ ; ready: unit Lwt.t * unit Lwt.u (** A simple promise indicating if the shard has received READY. *)
+ ; recv: Frame.t Lwt_stream.t (** Receiver function for the websocket. *)
+ ; send: (Frame.t -> unit Lwt.t) (** Sender function for the websocket. *)
+ ; seq: int (** Current sequence number for the session. *)
+ ; session: string option (** Current session ID *)
+ ; shard_count: int (** Total number of shards. *)
+ ; url: string (** The websocket URL. *)
}
(** Wrapper around an internal state, used to wrap {!shard}. *)
@@ -44,7 +43,7 @@ module Shard : sig (** Send a heartbeat to Discord. This is handled automatically. *)
val heartbeat :
shard ->
- shard Deferred.t
+ shard Lwt.t
(** Set the status of the shard. *)
val set_status :
@@ -54,7 +53,7 @@ module Shard : sig ?since:int ->
?url:string ->
shard ->
- shard Deferred.t
+ shard Lwt.t
(** Request guild members for the shard's guild. Causes dispatch of multiple {{!Dispatch.members_chunk}member chunk} events. *)
val request_guild_members :
@@ -62,7 +61,7 @@ module Shard : sig ?limit:int ->
guild:Snowflake.t ->
shard ->
- shard Deferred.t
+ shard Lwt.t
(** Create a new shard *)
val create :
@@ -71,13 +70,13 @@ module Shard : sig ?compress:bool ->
?large_threshold:int ->
unit ->
- shard Deferred.t
+ shard Lwt.t
val shutdown :
?clean:bool ->
?restart:bool ->
shard t ->
- unit Deferred.t
+ unit Lwt.t
end
(** Calls {!Shard.set_status} for each shard registered with the sharder. *)
@@ -88,7 +87,7 @@ val set_status : ?since:int ->
?url:string ->
t ->
- Shard.shard list Deferred.t
+ unit Lwt.t
(** Calls {!Shard.request_guild_members} for each shard registered with the sharder. *)
val request_guild_members :
@@ -96,9 +95,9 @@ val request_guild_members : ?limit:int ->
guild:Snowflake.t ->
t ->
- Shard.shard list Deferred.t
+ unit Lwt.t
val shutdown_all :
- ?restart:bool ->
- t ->
- unit list Deferred.t
+ ?restart:bool ->
+ t ->
+ unit Lwt.t
diff --git a/lib/http/endpoints.ml b/lib/http/endpoints.ml index 8a2faea..9263207 100644 --- a/lib/http/endpoints.ml +++ b/lib/http/endpoints.ml @@ -1,4 +1,3 @@ -open Core
open Printf
let gateway = "/gateway"
diff --git a/lib/http/http.ml b/lib/http/http.ml index 9feb652..7d0b22e 100644 --- a/lib/http/http.ml +++ b/lib/http/http.ml @@ -1,5 +1,4 @@ -open Core
-open Async
+open Lwt.Infix
open Cohttp
module Base = struct
@@ -15,7 +14,7 @@ module Base = struct let process_request_body body =
body
|> Yojson.Safe.to_string
- |> Cohttp_async.Body.of_string
+ |> Cohttp_lwt.Body.of_string
let process_request_headers () =
let h = Header.init () in
@@ -30,39 +29,44 @@ module Base = struct let limit = match Response.headers resp |> Rl.rl_of_header with
| Some r -> r
| None -> Rl.default
- in Mvar.put (Rl.find_exn !rl path) limit
+ in Lwt_mvar.put (Rl.find path !rl) limit
>>= fun () ->
match resp |> Response.status |> Code.code_of_status with
- | 204 -> Deferred.Or_error.return `Null
- | code when Code.is_success code -> body |> Cohttp_async.Body.to_string >>| Yojson.Safe.from_string >>= Deferred.Or_error.return
+ | 204 -> Lwt_result.return `Null
+ | code when Code.is_success code -> body |> Cohttp_lwt.Body.to_string >|= Yojson.Safe.from_string >>= Lwt_result.return
| code ->
- body |> Cohttp_async.Body.to_string >>= fun body ->
- let headers = Response.sexp_of_t resp |> Sexp.to_string_hum in
- Logs.warn (fun m -> m "[Unsuccessful Response] [Code: %d]\n%s\n%s" code body headers);
- Deferred.Or_error.errorf "Unsuccessful response received: %d - %s" code body
+ body |> Cohttp_lwt.Body.to_string >>= fun body ->
+ let headers = Response.sexp_of_t resp |> Sexplib.Sexp.to_string_hum in
+ Logs_lwt.warn (fun m -> m "[Unsuccessful Response] [Code: %d]\n%s\n%s" code body headers) >>= fun () ->
+ Lwt_result.fail @@ Printf.sprintf "Unsuccessful response received: %d - %s" code body
let request ?(body=`Null) ?(query=[]) m path =
let limit, rlm = Rl.get_rl m path !rl in
rl := rlm;
- Mvar.take limit >>= fun limit ->
+ Lwt_mvar.take limit >>= fun limit ->
let process () =
let uri = Uri.add_query_params' (process_url path) query in
let headers = process_request_headers () in
let body = process_request_body body in
(match m with
- | `Delete -> Cohttp_async.Client.delete ~headers ~body uri
- | `Get -> Cohttp_async.Client.get ~headers uri
- | `Patch -> Cohttp_async.Client.patch ~headers ~body uri
- | `Post -> Cohttp_async.Client.post ~headers ~body uri
- | `Put -> Cohttp_async.Client.put ~headers ~body uri)
+ | `Delete -> Cohttp_lwt_unix.Client.delete ~headers ~body uri
+ | `Get -> Cohttp_lwt_unix.Client.get ~headers uri
+ | `Patch -> Cohttp_lwt_unix.Client.patch ~headers ~body uri
+ | `Post -> Cohttp_lwt_unix.Client.post ~headers ~body uri
+ | `Put -> Cohttp_lwt_unix.Client.put ~headers ~body uri)
>>= process_response path
in if limit.remaining > 0 then process ()
else
- let time = Time.(Span.of_int_sec limit.reset |> of_span_since_epoch) in
+ (* let time = Time.(Span.of_int_sec limit.reset |> of_span_since_epoch) in
Logs.debug (fun m -> m "Rate-limiting [Route: %s] [Duration: %d ms]" path Time.(diff time (Time.now ()) |> Span.to_ms |> Float.to_int) );
- Clock.at time >>= process
+ Clock.at time >>= process *)
+ process ()
end
+let r_map f = function
+| Ok v -> Ok (f v)
+| Error e -> Error e
+
let get_gateway () =
Base.request `Get Endpoints.gateway
@@ -70,51 +74,51 @@ let get_gateway_bot () = Base.request `Get Endpoints.gateway_bot
let get_channel channel_id =
- Base.request `Get (Endpoints.channel channel_id) >>| Result.map ~f:(fun c -> Channel_t.(channel_wrapper_of_yojson_exn c |> wrap))
+ Base.request `Get (Endpoints.channel channel_id) >|= r_map (fun c -> Channel_t.(channel_wrapper_of_yojson_exn c |> wrap))
let modify_channel channel_id body =
- Base.request ~body `Patch (Endpoints.channel channel_id) >>| Result.map ~f:(fun c -> Channel_t.(channel_wrapper_of_yojson_exn c |> wrap))
+ Base.request ~body `Patch (Endpoints.channel channel_id) >|= r_map (fun c -> Channel_t.(channel_wrapper_of_yojson_exn c |> wrap))
let delete_channel channel_id =
- Base.request `Delete (Endpoints.channel channel_id) >>| Result.map ~f:(fun c -> Channel_t.(channel_wrapper_of_yojson_exn c |> wrap))
+ Base.request `Delete (Endpoints.channel channel_id) >|= r_map (fun c -> Channel_t.(channel_wrapper_of_yojson_exn c |> wrap))
let get_messages channel_id limit (kind, id) =
Base.request ~query:[(kind, string_of_int id); ("limit", string_of_int limit)] `Get (Endpoints.channel_messages channel_id)
- >>| Result.map ~f:(fun l -> Yojson.Safe.Util.to_list l |> List.map ~f:Message_t.of_yojson_exn)
+ >|= r_map (fun l -> Yojson.Safe.Util.to_list l |> List.map Message_t.of_yojson_exn)
let get_message channel_id message_id =
- Base.request `Get (Endpoints.channel_message channel_id message_id) >>| Result.map ~f:Message_t.of_yojson_exn
+ Base.request `Get (Endpoints.channel_message channel_id message_id) >|= r_map Message_t.of_yojson_exn
let create_message channel_id body =
- Base.request ~body:body `Post (Endpoints.channel_messages channel_id) >>| Result.map ~f:Message_t.of_yojson_exn
+ Base.request ~body:body `Post (Endpoints.channel_messages channel_id) >|= r_map Message_t.of_yojson_exn
let create_reaction channel_id message_id emoji =
- Base.request `Put (Endpoints.channel_reaction_me channel_id message_id emoji) >>| Result.map ~f:ignore
+ Base.request `Put (Endpoints.channel_reaction_me channel_id message_id emoji) >|= r_map ignore
let delete_own_reaction channel_id message_id emoji =
- Base.request `Delete (Endpoints.channel_reaction_me channel_id message_id emoji) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.channel_reaction_me channel_id message_id emoji) >|= r_map ignore
let delete_reaction channel_id message_id emoji user_id =
- Base.request `Delete (Endpoints.channel_reaction channel_id message_id emoji user_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.channel_reaction channel_id message_id emoji user_id) >|= r_map ignore
let get_reactions channel_id message_id emoji =
Base.request `Get (Endpoints.channel_reactions_get channel_id message_id emoji)
- >>| Result.map ~f:(fun l -> Yojson.Safe.Util.to_list l |> List.map ~f:User_t.of_yojson_exn)
+ >|= r_map (fun l -> Yojson.Safe.Util.to_list l |> List.map User_t.of_yojson_exn)
let delete_reactions channel_id message_id =
- Base.request `Delete (Endpoints.channel_reactions_delete channel_id message_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.channel_reactions_delete channel_id message_id) >|= r_map ignore
let edit_message channel_id message_id body =
- Base.request ~body `Patch (Endpoints.channel_message channel_id message_id) >>| Result.map ~f:Message_t.of_yojson_exn
+ Base.request ~body `Patch (Endpoints.channel_message channel_id message_id) >|= r_map Message_t.of_yojson_exn
let delete_message channel_id message_id =
- Base.request `Delete (Endpoints.channel_message channel_id message_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.channel_message channel_id message_id) >|= r_map ignore
let bulk_delete channel_id body =
- Base.request ~body `Post (Endpoints.channel_bulk_delete channel_id) >>| Result.map ~f:ignore
+ Base.request ~body `Post (Endpoints.channel_bulk_delete channel_id) >|= r_map ignore
let edit_channel_permissions channel_id overwrite_id body =
- Base.request ~body `Put (Endpoints.channel_permission channel_id overwrite_id) >>| Result.map ~f:ignore
+ Base.request ~body `Put (Endpoints.channel_permission channel_id overwrite_id) >|= r_map ignore
let get_channel_invites channel_id =
Base.request `Get (Endpoints.channel_invites channel_id)
@@ -123,128 +127,128 @@ let create_channel_invite channel_id body = Base.request ~body `Post (Endpoints.channel_invites channel_id)
let delete_channel_permission channel_id overwrite_id =
- Base.request `Delete (Endpoints.channel_permission channel_id overwrite_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.channel_permission channel_id overwrite_id) >|= r_map ignore
let broadcast_typing channel_id =
- Base.request `Post (Endpoints.channel_typing channel_id) >>| Result.map ~f:ignore
+ Base.request `Post (Endpoints.channel_typing channel_id) >|= r_map ignore
let get_pinned_messages channel_id =
Base.request `Get (Endpoints.channel_pins channel_id)
- >>| Result.map ~f:(fun l -> Yojson.Safe.Util.to_list l |> List.map ~f:Message_t.of_yojson_exn)
+ >|= r_map (fun l -> Yojson.Safe.Util.to_list l |> List.map Message_t.of_yojson_exn)
let pin_message channel_id message_id =
- Base.request `Put (Endpoints.channel_pin channel_id message_id) >>| Result.map ~f:ignore
+ Base.request `Put (Endpoints.channel_pin channel_id message_id) >|= r_map ignore
let unpin_message channel_id message_id =
- Base.request `Delete (Endpoints.channel_pin channel_id message_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.channel_pin channel_id message_id) >|= r_map ignore
let group_recipient_add channel_id user_id =
- Base.request `Put (Endpoints.group_recipient channel_id user_id) >>| Result.map ~f:ignore
+ Base.request `Put (Endpoints.group_recipient channel_id user_id) >|= r_map ignore
let group_recipient_remove channel_id user_id =
- Base.request `Delete (Endpoints.group_recipient channel_id user_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.group_recipient channel_id user_id) >|= r_map ignore
let get_emojis guild_id =
Base.request `Get (Endpoints.guild_emojis guild_id)
- >>| Result.map ~f:(fun l -> Yojson.Safe.Util.to_list l |> List.map ~f:Emoji.of_yojson_exn)
+ >|= r_map (fun l -> Yojson.Safe.Util.to_list l |> List.map Emoji.of_yojson_exn)
let get_emoji guild_id emoji_id =
- Base.request `Get (Endpoints.guild_emoji guild_id emoji_id) >>| Result.map ~f:Emoji.of_yojson_exn
+ Base.request `Get (Endpoints.guild_emoji guild_id emoji_id) >|= r_map Emoji.of_yojson_exn
let create_emoji guild_id body =
- Base.request ~body `Post (Endpoints.guild_emojis guild_id) >>| Result.map ~f:Emoji.of_yojson_exn
+ Base.request ~body `Post (Endpoints.guild_emojis guild_id) >|= r_map Emoji.of_yojson_exn
let edit_emoji guild_id emoji_id body =
- Base.request ~body `Patch (Endpoints.guild_emoji guild_id emoji_id) >>| Result.map ~f:Emoji.of_yojson_exn
+ Base.request ~body `Patch (Endpoints.guild_emoji guild_id emoji_id) >|= r_map Emoji.of_yojson_exn
let delete_emoji guild_id emoji_id =
- Base.request `Delete (Endpoints.guild_emoji guild_id emoji_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.guild_emoji guild_id emoji_id) >|= r_map ignore
let create_guild body =
- Base.request ~body `Post Endpoints.guilds >>| Result.map ~f:(fun g -> Guild_t.(pre_of_yojson_exn g |> wrap))
+ Base.request ~body `Post Endpoints.guilds >|= r_map (fun g -> Guild_t.(pre_of_yojson_exn g |> wrap))
let get_guild guild_id =
- Base.request `Get (Endpoints.guild guild_id) >>| Result.map ~f:(fun g -> Guild_t.(pre_of_yojson_exn g |> wrap))
+ Base.request `Get (Endpoints.guild guild_id) >|= r_map (fun g -> Guild_t.(pre_of_yojson_exn g |> wrap))
let edit_guild guild_id body =
- Base.request ~body `Patch (Endpoints.guild guild_id) >>| Result.map ~f:(fun g -> Guild_t.(pre_of_yojson_exn g |> wrap))
+ Base.request ~body `Patch (Endpoints.guild guild_id) >|= r_map (fun g -> Guild_t.(pre_of_yojson_exn g |> wrap))
let delete_guild guild_id =
- Base.request `Delete (Endpoints.guild guild_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.guild guild_id) >|= r_map ignore
let get_guild_channels guild_id =
Base.request `Get (Endpoints.guild_channels guild_id)
- >>| Result.map ~f:(fun l -> Yojson.Safe.Util.to_list l |> List.map ~f:(fun g -> Channel_t.(channel_wrapper_of_yojson_exn g |> wrap)))
+ >|= r_map (fun l -> Yojson.Safe.Util.to_list l |> List.map (fun g -> Channel_t.(channel_wrapper_of_yojson_exn g |> wrap)))
let create_guild_channel guild_id body =
- Base.request ~body `Post (Endpoints.guild_channels guild_id) >>| Result.map ~f:(fun c -> Channel_t.(channel_wrapper_of_yojson_exn c |> wrap))
+ Base.request ~body `Post (Endpoints.guild_channels guild_id) >|= r_map (fun c -> Channel_t.(channel_wrapper_of_yojson_exn c |> wrap))
let modify_guild_channel_positions guild_id body =
- Base.request ~body `Patch (Endpoints.guild_channels guild_id) >>| Result.map ~f:ignore
+ Base.request ~body `Patch (Endpoints.guild_channels guild_id) >|= r_map ignore
let get_member guild_id user_id =
- Base.request `Get (Endpoints.guild_member guild_id user_id) >>| Result.map ~f:(fun m -> Member_t.(member_of_yojson_exn m |> wrap ~guild_id))
+ Base.request `Get (Endpoints.guild_member guild_id user_id) >|= r_map (fun m -> Member_t.(member_of_yojson_exn m |> wrap ~guild_id))
let get_members guild_id =
Base.request `Get (Endpoints.guild_members guild_id)
- >>| Result.map ~f:(fun l -> Yojson.Safe.Util.to_list l |> List.map ~f:(fun m -> Member_t.(member_of_yojson_exn m |> wrap ~guild_id)))
+ >|= r_map (fun l -> Yojson.Safe.Util.to_list l |> List.map (fun m -> Member_t.(member_of_yojson_exn m |> wrap ~guild_id)))
let add_member guild_id user_id body =
Base.request ~body `Put (Endpoints.guild_member guild_id user_id)
- >>| Result.map ~f:(fun m -> Member_t.(member_of_yojson_exn m |> wrap ~guild_id))
+ >|= r_map (fun m -> Member_t.(member_of_yojson_exn m |> wrap ~guild_id))
let edit_member guild_id user_id body =
- Base.request ~body `Patch (Endpoints.guild_member guild_id user_id) >>| Result.map ~f:ignore
+ Base.request ~body `Patch (Endpoints.guild_member guild_id user_id) >|= r_map ignore
let remove_member guild_id user_id body =
- Base.request ~body `Delete (Endpoints.guild_member guild_id user_id) >>| Result.map ~f:ignore
+ Base.request ~body `Delete (Endpoints.guild_member guild_id user_id) >|= r_map ignore
let change_nickname guild_id body =
Base.request ~body `Patch (Endpoints.guild_me_nick guild_id)
let add_member_role guild_id user_id role_id =
- Base.request `Put (Endpoints.guild_member_role guild_id user_id role_id) >>| Result.map ~f:ignore
+ Base.request `Put (Endpoints.guild_member_role guild_id user_id role_id) >|= r_map ignore
let remove_member_role guild_id user_id role_id =
- Base.request `Delete (Endpoints.guild_member_role guild_id user_id role_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.guild_member_role guild_id user_id role_id) >|= r_map ignore
let get_bans guild_id =
Base.request `Get (Endpoints.guild_bans guild_id)
- >>| Result.map ~f:(fun l -> Yojson.Safe.Util.to_list l |> List.map ~f:Ban_t.of_yojson_exn)
+ >|= r_map (fun l -> Yojson.Safe.Util.to_list l |> List.map Ban_t.of_yojson_exn)
let get_ban guild_id user_id =
- Base.request `Get (Endpoints.guild_ban guild_id user_id) >>| Result.map ~f:Ban_t.of_yojson_exn
+ Base.request `Get (Endpoints.guild_ban guild_id user_id) >|= r_map Ban_t.of_yojson_exn
let guild_ban_add guild_id user_id body =
- Base.request ~body `Put (Endpoints.guild_ban guild_id user_id) >>| Result.map ~f:ignore
+ Base.request ~body `Put (Endpoints.guild_ban guild_id user_id) >|= r_map ignore
let guild_ban_remove guild_id user_id body =
- Base.request ~body `Delete (Endpoints.guild_ban guild_id user_id) >>| Result.map ~f:ignore
+ Base.request ~body `Delete (Endpoints.guild_ban guild_id user_id) >|= r_map ignore
let get_roles guild_id =
Base.request `Get (Endpoints.guild_roles guild_id)
- >>| Result.map ~f:(fun l -> Yojson.Safe.Util.to_list l |> List.map ~f:(fun r -> Role_t.(role_of_yojson_exn r |> wrap ~guild_id)))
+ >|= r_map (fun l -> Yojson.Safe.Util.to_list l |> List.map (fun r -> Role_t.(role_of_yojson_exn r |> wrap ~guild_id)))
let guild_role_add guild_id body =
- Base.request ~body `Post (Endpoints.guild_roles guild_id) >>| Result.map ~f:(fun r -> Role_t.(role_of_yojson_exn r |> wrap ~guild_id))
+ Base.request ~body `Post (Endpoints.guild_roles guild_id) >|= r_map (fun r -> Role_t.(role_of_yojson_exn r |> wrap ~guild_id))
let guild_roles_edit guild_id body =
Base.request ~body `Patch (Endpoints.guild_roles guild_id)
- >>| Result.map ~f:(fun l -> Yojson.Safe.Util.to_list l |> List.map ~f:(fun r -> Role_t.(role_of_yojson_exn r |> wrap ~guild_id)))
+ >|= r_map (fun l -> Yojson.Safe.Util.to_list l |> List.map (fun r -> Role_t.(role_of_yojson_exn r |> wrap ~guild_id)))
let guild_role_edit guild_id role_id body =
- Base.request ~body `Patch (Endpoints.guild_role guild_id role_id) >>| Result.map ~f:(fun r -> Role_t.(role_of_yojson_exn r |> wrap ~guild_id))
+ Base.request ~body `Patch (Endpoints.guild_role guild_id role_id) >|= r_map (fun r -> Role_t.(role_of_yojson_exn r |> wrap ~guild_id))
let guild_role_remove guild_id role_id =
- Base.request `Delete (Endpoints.guild_role guild_id role_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.guild_role guild_id role_id) >|= r_map ignore
let guild_prune_count guild_id days =
- Base.request ~query:[("days", Int.to_string days)] `Get (Endpoints.guild_prune guild_id)
- >>| Result.map ~f:(fun c -> Yojson.Safe.Util.(member "pruned" c |> to_int))
+ Base.request ~query:[("days", string_of_int days)] `Get (Endpoints.guild_prune guild_id)
+ >|= r_map (fun c -> Yojson.Safe.Util.(member "pruned" c |> to_int))
let guild_prune_start guild_id days =
- Base.request ~query:[("days", Int.to_string days)] `Post (Endpoints.guild_prune guild_id)
- >>| Result.map ~f:(fun c -> Yojson.Safe.Util.(member "pruned" c |> to_int))
+ Base.request ~query:[("days", string_of_int days)] `Post (Endpoints.guild_prune guild_id)
+ >|= r_map (fun c -> Yojson.Safe.Util.(member "pruned" c |> to_int))
let get_guild_voice_regions guild_id =
Base.request `Get (Endpoints.guild_voice_regions guild_id)
@@ -256,16 +260,16 @@ let get_integrations guild_id = Base.request `Get (Endpoints.guild_integrations guild_id)
let add_integration guild_id body =
- Base.request ~body `Post (Endpoints.guild_integrations guild_id) >>| Result.map ~f:ignore
+ Base.request ~body `Post (Endpoints.guild_integrations guild_id) >|= r_map ignore
let edit_integration guild_id integration_id body =
- Base.request ~body `Post (Endpoints.guild_integration guild_id integration_id) >>| Result.map ~f:ignore
+ Base.request ~body `Post (Endpoints.guild_integration guild_id integration_id) >|= r_map ignore
let delete_integration guild_id integration_id =
- Base.request `Delete (Endpoints.guild_integration guild_id integration_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.guild_integration guild_id integration_id) >|= r_map ignore
let sync_integration guild_id integration_id =
- Base.request `Post (Endpoints.guild_integration_sync guild_id integration_id) >>| Result.map ~f:ignore
+ Base.request `Post (Endpoints.guild_integration_sync guild_id integration_id) >|= r_map ignore
let get_guild_embed guild_id =
Base.request `Get (Endpoints.guild_embed guild_id)
@@ -283,17 +287,17 @@ let delete_invite invite_code = Base.request `Delete (Endpoints.invite invite_code)
let get_current_user () =
- Base.request `Get Endpoints.me >>| Result.map ~f:User_t.of_yojson_exn
+ Base.request `Get Endpoints.me >|= r_map User_t.of_yojson_exn
let edit_current_user body =
- Base.request ~body `Patch Endpoints.me >>| Result.map ~f:User_t.of_yojson_exn
+ Base.request ~body `Patch Endpoints.me >|= r_map User_t.of_yojson_exn
let get_guilds () =
Base.request `Get Endpoints.me_guilds
- >>| Result.map ~f:(fun l -> Yojson.Safe.Util.to_list l |> List.map ~f:(fun g -> Guild_t.(pre_of_yojson_exn g |> wrap)))
+ >|= r_map (fun l -> Yojson.Safe.Util.to_list l |> List.map (fun g -> Guild_t.(pre_of_yojson_exn g |> wrap)))
let leave_guild guild_id =
- Base.request `Delete (Endpoints.me_guild guild_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.me_guild guild_id) >|= r_map ignore
let get_private_channels () =
Base.request `Get Endpoints.me_channels
@@ -308,7 +312,7 @@ let get_connections () = Base.request `Get Endpoints.me_connections
let get_user user_id =
- Base.request `Get (Endpoints.user user_id) >>| Result.map ~f:User_t.of_yojson_exn
+ Base.request `Get (Endpoints.user user_id) >|= r_map User_t.of_yojson_exn
let get_voice_regions () =
Base.request `Get Endpoints.regions
@@ -335,10 +339,10 @@ let edit_webhook_with_token webhook_id token body = Base.request ~body `Patch (Endpoints.webhook_token webhook_id token)
let delete_webhook webhook_id =
- Base.request `Delete (Endpoints.webhook webhook_id) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.webhook webhook_id) >|= r_map ignore
let delete_webhook_with_token webhook_id token =
- Base.request `Delete (Endpoints.webhook_token webhook_id token) >>| Result.map ~f:ignore
+ Base.request `Delete (Endpoints.webhook_token webhook_id token) >|= r_map ignore
let execute_webhook webhook_id token body =
Base.request ~body `Post (Endpoints.webhook_token webhook_id token)
diff --git a/lib/http/http.mli b/lib/http/http.mli index b043854..e4cd1e4 100644 --- a/lib/http/http.mli +++ b/lib/http/http.mli @@ -1,185 +1,183 @@ -open Async
-
module Base : sig
exception Invalid_Method
val base_url : string
val process_url : string -> Uri.t
- val process_request_body : Yojson.Safe.t -> Cohttp_async.Body.t
+ val process_request_body : Yojson.Safe.t -> Cohttp_lwt.Body.t
val process_request_headers : unit -> Cohttp.Header.t
val process_response :
string ->
- Cohttp_async.Response.t * Cohttp_async.Body.t ->
- Yojson.Safe.t Deferred.Or_error.t
+ Cohttp_lwt.Response.t * Cohttp_lwt.Body.t ->
+ (Yojson.Safe.t, string) Lwt_result.t
val request :
?body:Yojson.Safe.t ->
?query:(string * string) list ->
[ `Delete | `Get | `Patch | `Post | `Put ] ->
string ->
- Yojson.Safe.t Deferred.Or_error.t
+ (Yojson.Safe.t, string) Lwt_result.t
end
-val get_gateway : unit -> Yojson.Safe.t Deferred.Or_error.t
-val get_gateway_bot : unit -> Yojson.Safe.t Deferred.Or_error.t
-val get_channel : int -> Channel_t.t Deferred.Or_error.t
+val get_gateway : unit -> (Yojson.Safe.t, string) Lwt_result.t
+val get_gateway_bot : unit -> (Yojson.Safe.t, string) Lwt_result.t
+val get_channel : int -> (Channel_t.t, string) Lwt_result.t
val modify_channel :
- int -> Yojson.Safe.t -> Channel_t.t Deferred.Or_error.t
-val delete_channel : int -> Channel_t.t Deferred.Or_error.t
-val get_messages : int -> int -> string * int -> Message_t.t list Deferred.Or_error.t
-val get_message : int -> int -> Message_t.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Channel_t.t, string) Lwt_result.t
+val delete_channel : int -> (Channel_t.t, string) Lwt_result.t
+val get_messages : int -> int -> string * int -> (Message_t.t list, string) Lwt_result.t
+val get_message : int -> int -> (Message_t.t, string) Lwt_result.t
val create_message :
- int -> Yojson.Safe.t -> Message_t.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Message_t.t, string) Lwt_result.t
val create_reaction :
- int -> int -> string -> unit Deferred.Or_error.t
+ int -> int -> string -> (unit, string) Lwt_result.t
val delete_own_reaction :
- int -> int -> string -> unit Deferred.Or_error.t
+ int -> int -> string -> (unit, string) Lwt_result.t
val delete_reaction :
- int -> int -> string -> int -> unit Deferred.Or_error.t
+ int -> int -> string -> int -> (unit, string) Lwt_result.t
val get_reactions :
- int -> int -> string -> User_t.t list Deferred.Or_error.t
+ int -> int -> string -> (User_t.t list, string) Lwt_result.t
val delete_reactions :
- int -> int -> unit Deferred.Or_error.t
+ int -> int -> (unit, string) Lwt_result.t
val edit_message :
int ->
- int -> Yojson.Safe.t -> Message_t.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Message_t.t, string) Lwt_result.t
val delete_message :
- int -> int -> unit Deferred.Or_error.t
+ int -> int -> (unit, string) Lwt_result.t
val bulk_delete :
- int -> Yojson.Safe.t -> unit Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (unit, string) Lwt_result.t
val edit_channel_permissions :
int ->
- int -> Yojson.Safe.t -> unit Deferred.Or_error.t
-val get_channel_invites : int -> Yojson.Safe.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (unit, string) Lwt_result.t
+val get_channel_invites : int -> (Yojson.Safe.t, string) Lwt_result.t
val create_channel_invite :
- int -> Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
val delete_channel_permission :
- int -> int -> unit Deferred.Or_error.t
-val broadcast_typing : int -> unit Deferred.Or_error.t
-val get_pinned_messages : int -> Message_t.t list Deferred.Or_error.t
-val pin_message : int -> int -> unit Deferred.Or_error.t
-val unpin_message : int -> int -> unit Deferred.Or_error.t
+ int -> int -> (unit, string) Lwt_result.t
+val broadcast_typing : int -> (unit, string) Lwt_result.t
+val get_pinned_messages : int -> (Message_t.t list, string) Lwt_result.t
+val pin_message : int -> int -> (unit, string) Lwt_result.t
+val unpin_message : int -> int -> (unit, string) Lwt_result.t
val group_recipient_add :
- int -> int -> unit Deferred.Or_error.t
+ int -> int -> (unit, string) Lwt_result.t
val group_recipient_remove :
- int -> int -> unit Deferred.Or_error.t
-val get_emojis : int -> Emoji.t list Deferred.Or_error.t
-val get_emoji : int -> int -> Emoji.t Deferred.Or_error.t
+ int -> int -> (unit, string) Lwt_result.t
+val get_emojis : int -> (Emoji.t list, string) Lwt_result.t
+val get_emoji : int -> int -> (Emoji.t, string) Lwt_result.t
val create_emoji :
- int -> Yojson.Safe.t -> Emoji.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Emoji.t, string) Lwt_result.t
val edit_emoji :
int ->
- int -> Yojson.Safe.t -> Emoji.t Deferred.Or_error.t
-val delete_emoji : int -> int -> unit Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Emoji.t, string) Lwt_result.t
+val delete_emoji : int -> int -> (unit, string) Lwt_result.t
val create_guild :
- Yojson.Safe.t -> Guild_t.t Deferred.Or_error.t
-val get_guild : int -> Guild_t.t Deferred.Or_error.t
+ Yojson.Safe.t -> (Guild_t.t, string) Lwt_result.t
+val get_guild : int -> (Guild_t.t, string) Lwt_result.t
val edit_guild :
- int -> Yojson.Safe.t -> Guild_t.t Deferred.Or_error.t
-val delete_guild : int -> unit Deferred.Or_error.t
-val get_guild_channels : int -> Channel_t.t list Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Guild_t.t, string) Lwt_result.t
+val delete_guild : int -> (unit, string) Lwt_result.t
+val get_guild_channels : int -> (Channel_t.t list, string) Lwt_result.t
val create_guild_channel :
- int -> Yojson.Safe.t -> Channel_t.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Channel_t.t, string) Lwt_result.t
val modify_guild_channel_positions :
- int -> Yojson.Safe.t -> unit Deferred.Or_error.t
-val get_member : int -> int -> Member.t Deferred.Or_error.t
-val get_members : int -> Member.t list Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (unit, string) Lwt_result.t
+val get_member : int -> int -> (Member.t, string) Lwt_result.t
+val get_members : int -> (Member.t list, string) Lwt_result.t
val add_member :
int ->
- int -> Yojson.Safe.t -> Member.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Member.t, string) Lwt_result.t
val edit_member :
int ->
- int -> Yojson.Safe.t -> unit Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (unit, string) Lwt_result.t
val remove_member :
int ->
- int -> Yojson.Safe.t -> unit Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (unit, string) Lwt_result.t
val change_nickname :
- int -> Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
val add_member_role :
- int -> int -> int -> unit Deferred.Or_error.t
+ int -> int -> int -> (unit, string) Lwt_result.t
val remove_member_role :
- int -> int -> int -> unit Deferred.Or_error.t
-val get_bans : int -> Ban.t list Deferred.Or_error.t
-val get_ban : int -> int -> Ban.t Deferred.Or_error.t
+ int -> int -> int -> (unit, string) Lwt_result.t
+val get_bans : int -> (Ban.t list, string) Lwt_result.t
+val get_ban : int -> int -> (Ban.t, string) Lwt_result.t
val guild_ban_add :
int ->
- int -> Yojson.Safe.t -> unit Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (unit, string) Lwt_result.t
val guild_ban_remove :
int ->
- int -> Yojson.Safe.t -> unit Deferred.Or_error.t
-val get_roles : int -> Role_t.t list Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (unit, string) Lwt_result.t
+val get_roles : int -> (Role_t.t list, string) Lwt_result.t
val guild_role_add :
- int -> Yojson.Safe.t -> Role_t.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Role_t.t, string) Lwt_result.t
val guild_roles_edit :
- int -> Yojson.Safe.t -> Role_t.t list Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Role_t.t list, string) Lwt_result.t
val guild_role_edit :
int ->
- int -> Yojson.Safe.t -> Role_t.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Role_t.t, string) Lwt_result.t
val guild_role_remove :
- int -> int -> unit Deferred.Or_error.t
+ int -> int -> (unit, string) Lwt_result.t
val guild_prune_count :
- int -> int -> int Deferred.Or_error.t
+ int -> int -> (int, string) Lwt_result.t
val guild_prune_start :
- int -> int -> int Deferred.Or_error.t
+ int -> int -> (int, string) Lwt_result.t
val get_guild_voice_regions :
- int -> Yojson.Safe.t Deferred.Or_error.t
-val get_guild_invites : int -> Yojson.Safe.t Deferred.Or_error.t
-val get_integrations : int -> Yojson.Safe.t Deferred.Or_error.t
+ int -> (Yojson.Safe.t, string) Lwt_result.t
+val get_guild_invites : int -> (Yojson.Safe.t, string) Lwt_result.t
+val get_integrations : int -> (Yojson.Safe.t, string) Lwt_result.t
val add_integration :
- int -> Yojson.Safe.t -> unit Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (unit, string) Lwt_result.t
val edit_integration :
int ->
- int -> Yojson.Safe.t -> unit Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (unit, string) Lwt_result.t
val delete_integration :
- int -> int -> unit Deferred.Or_error.t
+ int -> int -> (unit, string) Lwt_result.t
val sync_integration :
- int -> int -> unit Deferred.Or_error.t
-val get_guild_embed : int -> Yojson.Safe.t Deferred.Or_error.t
+ int -> int -> (unit, string) Lwt_result.t
+val get_guild_embed : int -> (Yojson.Safe.t, string) Lwt_result.t
val edit_guild_embed :
- int -> Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
-val get_vanity_url : int -> Yojson.Safe.t Deferred.Or_error.t
-val get_invite : string -> Yojson.Safe.t Deferred.Or_error.t
-val delete_invite : string -> Yojson.Safe.t Deferred.Or_error.t
-val get_current_user : unit -> User_t.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
+val get_vanity_url : int -> (Yojson.Safe.t, string) Lwt_result.t
+val get_invite : string -> (Yojson.Safe.t, string) Lwt_result.t
+val delete_invite : string -> (Yojson.Safe.t, string) Lwt_result.t
+val get_current_user : unit -> (User_t.t, string) Lwt_result.t
val edit_current_user :
- Yojson.Safe.t -> User_t.t Deferred.Or_error.t
-val get_guilds : unit -> Guild_t.t list Deferred.Or_error.t
-val leave_guild : int -> unit Deferred.Or_error.t
+ Yojson.Safe.t -> (User_t.t, string) Lwt_result.t
+val get_guilds : unit -> (Guild_t.t list, string) Lwt_result.t
+val leave_guild : int -> (unit, string) Lwt_result.t
val get_private_channels :
- unit -> Yojson.Safe.t Deferred.Or_error.t
+ unit -> (Yojson.Safe.t, string) Lwt_result.t
val create_dm :
- Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
+ Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
val create_group_dm :
- Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
-val get_connections : unit -> Yojson.Safe.t Deferred.Or_error.t
-val get_user : int -> User_t.t Deferred.Or_error.t
-val get_voice_regions : unit -> Yojson.Safe.t Deferred.Or_error.t
+ Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
+val get_connections : unit -> (Yojson.Safe.t, string) Lwt_result.t
+val get_user : int -> (User_t.t, string) Lwt_result.t
+val get_voice_regions : unit -> (Yojson.Safe.t, string) Lwt_result.t
val create_webhook :
- int -> Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
-val get_channel_webhooks : int -> Yojson.Safe.t Deferred.Or_error.t
-val get_guild_webhooks : int -> Yojson.Safe.t Deferred.Or_error.t
-val get_webhook : int -> Yojson.Safe.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
+val get_channel_webhooks : int -> (Yojson.Safe.t, string) Lwt_result.t
+val get_guild_webhooks : int -> (Yojson.Safe.t, string) Lwt_result.t
+val get_webhook : int -> (Yojson.Safe.t, string) Lwt_result.t
val get_webhook_with_token :
- int -> string -> Yojson.Safe.t Deferred.Or_error.t
+ int -> string -> (Yojson.Safe.t, string) Lwt_result.t
val edit_webhook :
- int -> Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
+ int -> Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
val edit_webhook_with_token :
int ->
- string -> Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
-val delete_webhook : int -> unit Deferred.Or_error.t
+ string -> Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
+val delete_webhook : int -> (unit, string) Lwt_result.t
val delete_webhook_with_token :
- int -> string -> unit Deferred.Or_error.t
+ int -> string -> (unit, string) Lwt_result.t
val execute_webhook :
int ->
- string -> Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
+ string -> Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
val execute_slack_webhook :
int ->
- string -> Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
+ string -> Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
val execute_git_webhook :
int ->
- string -> Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
+ string -> Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
val get_audit_logs :
- int -> Yojson.Safe.t -> Yojson.Safe.t Deferred.Or_error.t
-val get_application_info : unit -> Yojson.Safe.t Deferred.Or_error.t
\ No newline at end of file + int -> Yojson.Safe.t -> (Yojson.Safe.t, string) Lwt_result.t
+val get_application_info : unit -> (Yojson.Safe.t, string) Lwt_result.t
\ No newline at end of file diff --git a/lib/http/rl.ml b/lib/http/rl.ml index 9f149df..aa2f883 100644 --- a/lib/http/rl.ml +++ b/lib/http/rl.ml @@ -1,8 +1,8 @@ -open Core -open Async - module RouteMap = Map.Make(String) +let sexp_of_int = Base.Int.sexp_of_t +let int_of_sexp = Base.Int.t_of_sexp + type rl = { limit: int; remaining: int; @@ -10,7 +10,7 @@ type rl = { } [@@deriving sexp] (* TODO improve route getting, use Date header *) -type t = ((rl, read_write) Mvar.t) RouteMap.t +type t = rl Lwt_mvar.t RouteMap.t let r_message_delete = Str.regexp "/channel/[0-9]+/messages/" let r_emoji = Str.regexp "/channel/[0-9]+/messages/[0-9]+/reactions/[A-Za-z0-9_\\-]+/\\(@me|[0-9]+\\)" @@ -25,9 +25,9 @@ let rl_of_header h = let module C = Cohttp.Header in match C.get h "X-RateLimit-Limit", C.get h "X-RateLimit-Remaining", C.get h "X-RateLimit-Reset" with | Some lim, Some rem, Some re -> - let limit = Int.of_string lim in - let remaining = Int.of_string rem in - let reset = Int.of_string re in + let limit = int_of_string lim in + let remaining = int_of_string rem in + let reset = int_of_string re in Some { limit; remaining; reset; } | _ -> None @@ -35,16 +35,12 @@ let default = { limit = 1; remaining = 1; reset = 0; } let empty : t = RouteMap.empty let update = RouteMap.update let find = RouteMap.find -let find_exn m s = match find m s with - | Some r -> r - | None -> raise (Not_found_s (String.sexp_of_t s)) let get_rl meth path rl = let route = route_of_path meth path in - match RouteMap.find rl route with + match RouteMap.find_opt route rl with | Some r -> r, rl | None -> - let data = Mvar.create () in - Mvar.set data default; - let rl = RouteMap.add_exn rl ~key:route ~data in + let data = Lwt_mvar.create default in + let rl = RouteMap.add route data rl in data, rl
\ No newline at end of file diff --git a/lib/http/rl.mli b/lib/http/rl.mli index 54bc5ee..737dcd3 100644 --- a/lib/http/rl.mli +++ b/lib/http/rl.mli @@ -1,8 +1,5 @@ (** Internal ratelimit route mapping. *) -open Core -open Async - (** Type for mapping route -> {!rl}. *) module RouteMap : module type of Map.Make(String) @@ -14,13 +11,13 @@ type rl = { } [@@deriving sexp] (** Type representing the specific case of {!RouteMap}. *) -type t = ((rl, read_write) Mvar.t) RouteMap.t +type t = rl Lwt_mvar.t RouteMap.t val get_rl : [ `Get | `Delete | `Post | `Patch | `Put ] -> string -> t -> - (rl, read_write) Mvar.t * t + rl Lwt_mvar.t * t (** Converts Cohttp header data into ratelimit information. @return Some of ratelimit information or None on bad headers @@ -34,10 +31,7 @@ val default : rl val empty : t (** Analogous to {!RouteMap.update}. *) -val update : 'a RouteMap.t -> string -> f:('a option -> 'a) -> 'a RouteMap.t +val update : string -> ('a option -> 'a option) -> 'a RouteMap.t -> 'a RouteMap.t (** Analogous to {!RouteMap.find}. *) -val find : 'a RouteMap.t -> string -> 'a option - -(** Analogous to {!RouteMap.find_exn}. *) -val find_exn : 'a RouteMap.t -> string -> 'a
\ No newline at end of file +val find : string -> 'a RouteMap.t -> 'a
\ No newline at end of file diff --git a/lib/models/channel/channel.ml b/lib/models/channel/channel.ml index 47cf500..632570a 100644 --- a/lib/models/channel/channel.ml +++ b/lib/models/channel/channel.ml @@ -1,4 +1,3 @@ -open Core
include Channel_t
exception Invalid_message
@@ -51,5 +50,5 @@ let get_pins ch = Http.get_pinned_messages (get_id ch)
let bulk_delete msgs ch =
- let msgs = `List (List.map ~f:(fun id -> `Int id) msgs) in
+ let msgs = `List (List.map (fun id -> `Int id) msgs) in
Http.bulk_delete (get_id ch) msgs
\ No newline at end of file diff --git a/lib/models/channel/channel.mli b/lib/models/channel/channel.mli index 0d7431b..94022e7 100644 --- a/lib/models/channel/channel.mli +++ b/lib/models/channel/channel.mli @@ -1,4 +1,3 @@ -open Async
include module type of Channel_t
exception Invalid_message
@@ -27,20 +26,20 @@ val send_message : ?file:string ->
?tts:bool ->
t ->
- Message_t.t Deferred.Or_error.t
+ (Message_t.t, string) Lwt_result.t
(** [say str ch] is equivalent to [send_message ~content:str ch]. *)
-val say : string -> t -> Message_t.t Deferred.Or_error.t
+val say : string -> t -> (Message_t.t, string) Lwt_result.t
-val delete : t -> Channel_t.t Deferred.Or_error.t
-val get_message : id:Snowflake.t -> t -> Message_t.t Deferred.Or_error.t
+val delete : t -> (Channel_t.t, string) Lwt_result.t
+val get_message : id:Snowflake.t -> t -> (Message_t.t, string) Lwt_result.t
val get_messages :
?mode:[ `Before | `After | `Around ] ->
?id:Snowflake.t ->
?limit:int ->
t ->
- Message_t.t list Deferred.Or_error.t
-val broadcast_typing : t -> unit Deferred.Or_error.t
-val get_pins : t -> Message_t.t list Deferred.Or_error.t
-val bulk_delete : Snowflake.t list -> t -> unit Deferred.Or_error.t
+ (Message_t.t list, string) Lwt_result.t
+val broadcast_typing : t -> (unit, string) Lwt_result.t
+val get_pins : t -> (Message_t.t list, string) Lwt_result.t
+val bulk_delete : Snowflake.t list -> t -> (unit, string) Lwt_result.t
(* TODO more things related to guild channels *)
diff --git a/lib/models/channel/channel_t.ml b/lib/models/channel/channel_t.ml index e332c36..5c7aa86 100644 --- a/lib/models/channel/channel_t.ml +++ b/lib/models/channel/channel_t.ml @@ -1,4 +1,15 @@ -open Core
+let string_of_sexp = Base.String.t_of_sexp
+let sexp_of_string = Base.String.sexp_of_t
+let option_of_sexp = Base.Option.t_of_sexp
+let sexp_of_option = Base.Option.sexp_of_t
+let int_of_sexp = Base.Int.t_of_sexp
+let sexp_of_int = Base.Int.sexp_of_t
+let bool_of_sexp = Base.Bool.t_of_sexp
+let sexp_of_bool = Base.Bool.sexp_of_t
+let list_of_sexp = Base.List.t_of_sexp
+let sexp_of_list = Base.List.sexp_of_t
+
+module Option = Base.Option
exception Invalid_channel of Yojson.Safe.t
diff --git a/lib/models/channel/message/attachment.ml b/lib/models/channel/message/attachment.ml index d720a81..696df60 100644 --- a/lib/models/channel/message/attachment.ml +++ b/lib/models/channel/message/attachment.ml @@ -1,4 +1,7 @@ -open Core +let string_of_sexp = Base.String.t_of_sexp +let sexp_of_string = Base.String.sexp_of_t +let int_of_sexp = Base.Int.t_of_sexp +let sexp_of_int = Base.Int.sexp_of_t type t = { id: Snowflake.t; diff --git a/lib/models/channel/message/embed.ml b/lib/models/channel/message/embed.ml index 0dd7343..fdeed36 100644 --- a/lib/models/channel/message/embed.ml +++ b/lib/models/channel/message/embed.ml @@ -1,4 +1,13 @@ -open Core
+let string_of_sexp = Base.String.t_of_sexp
+let sexp_of_string = Base.String.sexp_of_t
+let option_of_sexp = Base.Option.t_of_sexp
+let sexp_of_option = Base.Option.sexp_of_t
+let int_of_sexp = Base.Int.t_of_sexp
+let sexp_of_int = Base.Int.sexp_of_t
+let bool_of_sexp = Base.Bool.t_of_sexp
+let sexp_of_bool = Base.Bool.sexp_of_t
+let list_of_sexp = Base.List.t_of_sexp
+let sexp_of_list = Base.List.sexp_of_t
type footer = {
text: string;
@@ -111,7 +120,7 @@ let image v e = { e with image = Some { default_image with url = Some v } } let thumbnail v e = { e with thumbnail = Some { default_image with url = Some v } }
let author f e = { e with author = Some (f default_author) }
let field (name, value, inline) e = { e with fields = { name; value; inline; }::e.fields }
-let fields l e = { e with fields = List.map ~f:(fun (name, value, inline) -> { name; value; inline; }) l }
+let fields l e = { e with fields = List.map (fun (name, value, inline) -> { name; value; inline; }) l }
let footer_text v f : footer = { f with text = v }
let footer_icon v f : footer = { f with icon_url = Some v }
diff --git a/lib/models/channel/message/message.ml b/lib/models/channel/message/message.ml index 41174e1..748a423 100644 --- a/lib/models/channel/message/message.ml +++ b/lib/models/channel/message/message.ml @@ -1,5 +1,3 @@ -open Core
-open Async
include Message_t
let add_reaction msg (emoji:Emoji.t) =
diff --git a/lib/models/channel/message/message.mli b/lib/models/channel/message/message.mli index 0eba3af..3e5f0de 100644 --- a/lib/models/channel/message/message.mli +++ b/lib/models/channel/message/message.mli @@ -1,27 +1,25 @@ -open Async
-
include module type of Message_t
(** Add the given emoji as a reaction. *)
-val add_reaction : t -> Emoji.t -> unit Deferred.Or_error.t
+val add_reaction : t -> Emoji.t -> (unit, string) Lwt_result.t
(** Remove the reaction. Must also specify the user. *)
-val remove_reaction : t -> Emoji.t -> User_t.t -> unit Deferred.Or_error.t
+val remove_reaction : t -> Emoji.t -> User_t.t -> (unit, string) Lwt_result.t
(** Remove all reactions from the message. *)
-val clear_reactions : t -> unit Deferred.Or_error.t
+val clear_reactions : t -> (unit, string) Lwt_result.t
(** Delete the message. *)
-val delete : t -> unit Deferred.Or_error.t
+val delete : t -> (unit, string) Lwt_result.t
(** Pin the message. *)
-val pin : t -> unit Deferred.Or_error.t
+val pin : t -> (unit, string) Lwt_result.t
(** Unping the message. *)
-val unpin : t -> unit Deferred.Or_error.t
+val unpin : t -> (unit, string) Lwt_result.t
(** Sugar for [Channel_id.say msg.channel_id content]. *)
-val reply : t -> string -> t Deferred.Or_error.t
+val reply : t -> string -> (t, string) Lwt_result.t
(** Sugar for [Channel_id.send_message ?embed ?content ?file ?tts msg.channel_id]. *)
val reply_with :
@@ -30,10 +28,10 @@ val reply_with : ?file:string ->
?tts:bool ->
t ->
- Message_t.t Deferred.Or_error.t
+ (Message_t.t, string) Lwt_result.t
(** Set the content of the message. *)
-val set_content : t -> string -> t Deferred.Or_error.t
+val set_content : t -> string -> (t, string) Lwt_result.t
(** Set the embed of the message. *)
-val set_embed : t -> Embed.t -> t Deferred.Or_error.t
+val set_embed : t -> Embed.t -> (t, string) Lwt_result.t
diff --git a/lib/models/channel/message/message_t.ml b/lib/models/channel/message/message_t.ml index 31fc88c..5963ee2 100644 --- a/lib/models/channel/message/message_t.ml +++ b/lib/models/channel/message/message_t.ml @@ -1,4 +1,13 @@ -open Core
+let string_of_sexp = Base.String.t_of_sexp
+let sexp_of_string = Base.String.sexp_of_t
+let option_of_sexp = Base.Option.t_of_sexp
+let sexp_of_option = Base.Option.sexp_of_t
+let int_of_sexp = Base.Int.t_of_sexp
+let sexp_of_int = Base.Int.sexp_of_t
+let bool_of_sexp = Base.Bool.t_of_sexp
+let sexp_of_bool = Base.Bool.sexp_of_t
+let list_of_sexp = Base.List.t_of_sexp
+let sexp_of_list = Base.List.sexp_of_t
type t = {
id: Message_id.t;
diff --git a/lib/models/channel/message/reaction_t.ml b/lib/models/channel/message/reaction_t.ml index e8ec5a0..9843fc4 100644 --- a/lib/models/channel/message/reaction_t.ml +++ b/lib/models/channel/message/reaction_t.ml @@ -1,4 +1,7 @@ -open Core
+let option_of_sexp = Base.Option.t_of_sexp
+let sexp_of_option = Base.Option.sexp_of_t
+let int_of_sexp = Base.Int.t_of_sexp
+let sexp_of_int = Base.Int.sexp_of_t
type reaction_event = {
user_id: User_id_t.t;
diff --git a/lib/models/emoji.ml b/lib/models/emoji.ml index 09a51ab..cafb424 100644 --- a/lib/models/emoji.ml +++ b/lib/models/emoji.ml @@ -1,4 +1,11 @@ -open Core
+let string_of_sexp = Base.String.t_of_sexp
+let sexp_of_string = Base.String.sexp_of_t
+let option_of_sexp = Base.Option.t_of_sexp
+let sexp_of_option = Base.Option.sexp_of_t
+let bool_of_sexp = Base.Bool.t_of_sexp
+let sexp_of_bool = Base.Bool.sexp_of_t
+let list_of_sexp = Base.List.t_of_sexp
+let sexp_of_list = Base.List.sexp_of_t
type partial_emoji = {
id: Snowflake.t option [@default None];
diff --git a/lib/models/event_models.ml b/lib/models/event_models.ml index 603f2c3..14b730f 100644 --- a/lib/models/event_models.ml +++ b/lib/models/event_models.ml @@ -1,4 +1,13 @@ -open Core
+let string_of_sexp = Base.String.t_of_sexp
+let sexp_of_string = Base.String.sexp_of_t
+let option_of_sexp = Base.Option.t_of_sexp
+let sexp_of_option = Base.Option.sexp_of_t
+let int_of_sexp = Base.Int.t_of_sexp
+let sexp_of_int = Base.Int.sexp_of_t
+let bool_of_sexp = Base.Bool.t_of_sexp
+let sexp_of_bool = Base.Bool.sexp_of_t
+let list_of_sexp = Base.List.t_of_sexp
+let sexp_of_list = Base.List.sexp_of_t
module ChannelCreate = struct
type t = Channel_t.t
@@ -10,24 +19,24 @@ module ChannelCreate = struct let module C = Cache.ChannelMap in
match t with
| `GuildText c ->
- let text_channels = C.update cache.text_channels c.id ~f:(function
- | Some _ | None -> c) in
+ let text_channels = C.update c.id (function
+ | Some _ | None -> Some c) cache.text_channels in
{ cache with text_channels }
| `GuildVoice c ->
- let voice_channels = C.update cache.voice_channels c.id ~f:(function
- | Some _ | None -> c) in
+ let voice_channels = C.update c.id (function
+ | Some _ | None -> Some c) cache.voice_channels in
{ cache with voice_channels }
| `Category c ->
- let categories = C.update cache.categories c.id ~f:(function
- | Some _ | None -> c) in
+ let categories = C.update c.id (function
+ | Some _ | None -> Some c) cache.categories in
{ cache with categories }
| `Group c ->
- let groups = C.update cache.groups c.id ~f:(function
- | Some _ | None -> c) in
+ let groups = C.update c.id (function
+ | Some _ | None -> Some c) cache.groups in
{ cache with groups }
| `Private c ->
- let private_channels = C.update cache.private_channels c.id ~f:(function
- | Some _ | None -> c) in
+ let private_channels = C.update c.id (function
+ | Some _ | None -> Some c) cache.private_channels in
{ cache with private_channels }
end
@@ -41,19 +50,19 @@ module ChannelDelete = struct let module C = Cache.ChannelMap in
match t with
| `GuildText c ->
- let text_channels = C.remove cache.text_channels c.id in
+ let text_channels = C.remove c.id cache.text_channels in
{ cache with text_channels }
| `GuildVoice c ->
- let voice_channels = C.remove cache.voice_channels c.id in
+ let voice_channels = C.remove c.id cache.voice_channels in
{ cache with voice_channels }
| `Category c ->
- let categories = C.remove cache.categories c.id in
+ let categories = C.remove c.id cache.categories in
{ cache with categories }
| `Group c ->
- let groups = C.remove cache.groups c.id in
+ let groups = C.remove c.id cache.groups in
{ cache with groups }
| `Private c ->
- let private_channels = C.remove cache.private_channels c.id in
+ let private_channels = C.remove c.id cache.private_channels in
{ cache with private_channels }
end
@@ -67,29 +76,29 @@ module ChannelUpdate = struct let module C = Cache.ChannelMap in
match t with
| `GuildText c ->
- let text_channels = C.update cache.text_channels c.id ~f:(function
- | Some _ -> c
- | None -> c) in
+ let text_channels = C.update c.id (function
+ | Some _ | None -> Some c)
+ cache.text_channels in
{ cache with text_channels }
| `GuildVoice c ->
- let voice_channels = C.update cache.voice_channels c.id ~f:(function
- | Some _ -> c
- | None -> c) in
+ let voice_channels = C.update c.id (function
+ | Some _ | None -> Some c)
+ cache.voice_channels in
{ cache with voice_channels }
| `Category c ->
- let categories = C.update cache.categories c.id ~f:(function
- | Some _ -> c
- | None -> c) in
+ let categories = C.update c.id (function
+ | Some _ | None -> Some c)
+ cache.categories in
{ cache with categories }
| `Group c ->
- let groups = C.update cache.groups c.id ~f:(function
- | Some _ -> c
- | None -> c) in
+ let groups = C.update c.id (function
+ | Some _ | None -> Some c)
+ cache.groups in
{ cache with groups }
| `Private c ->
- let private_channels = C.update cache.private_channels c.id ~f:(function
- | Some _ -> c
- | None -> c) in
+ let private_channels = C.update c.id (function
+ | Some _ | None -> Some c)
+ cache.private_channels in
{ cache with private_channels }
end
@@ -103,20 +112,17 @@ module ChannelPinsUpdate = struct let update_cache (cache:Cache.t) t =
let module C = Cache.ChannelMap in
- if C.mem cache.private_channels t.channel_id then
- let private_channels = match C.find cache.private_channels t.channel_id with
- | Some c -> C.set cache.private_channels ~key:t.channel_id ~data:{ c with last_pin_timestamp = t.last_pin_timestamp }
- | None -> cache.private_channels in
+ if C.mem t.channel_id cache.private_channels then
+ let c = C.find t.channel_id cache.private_channels in
+ let private_channels = C.add t.channel_id { c with last_pin_timestamp = t.last_pin_timestamp } cache.private_channels in
{ cache with private_channels }
- else if C.mem cache.text_channels t.channel_id then
- let text_channels = match C.find cache.text_channels t.channel_id with
- | Some c -> C.set cache.text_channels ~key:t.channel_id ~data:{ c with last_pin_timestamp = t.last_pin_timestamp }
- | None -> cache.text_channels in
+ else if C.mem t.channel_id cache.text_channels then
+ let c = C.find t.channel_id cache.text_channels in
+ let text_channels = C.add t.channel_id { c with last_pin_timestamp = t.last_pin_timestamp } cache.text_channels in
{ cache with text_channels }
- else if C.mem cache.groups t.channel_id then
- let groups = match C.find cache.groups t.channel_id with
- | Some c -> C.set cache.groups ~key:t.channel_id ~data:{ c with last_pin_timestamp = t.last_pin_timestamp }
- | None -> cache.groups in
+ else if C.mem t.channel_id cache.groups then
+ let c = C.find t.channel_id cache.groups in
+ let groups = C.add t.channel_id { c with last_pin_timestamp = t.last_pin_timestamp } cache.groups in
{ cache with groups }
else cache
end
@@ -177,35 +183,39 @@ module GuildCreate = struct let update_cache (cache:Cache.t) (t:t) =
let open Channel_t in
let module C = Cache.ChannelMap in
- let guilds = Cache.GuildMap.update cache.guilds t.id ~f:(function Some _ | None -> t) in
- let unavailable_guilds = Cache.GuildMap.remove cache.unavailable_guilds t.id in
+ let guilds = Cache.GuildMap.update t.id (function Some _ | None -> Some t) cache.guilds in
+ let unavailable_guilds = Cache.GuildMap.remove t.id cache.unavailable_guilds in
let text, voice, cat = ref [], ref [], ref [] in
- List.iter t.channels ~f:(function
- | `GuildText c -> text := (c.id, c) :: !text
- | `GuildVoice c -> voice := (c.id, c) :: !voice
- | `Category c -> cat := (c.id, c) :: !cat
- | _ -> ());
- let text_channels = match C.of_alist !text with
- | `Ok m ->
- C.merge m cache.text_channels ~f:(fun ~key -> function
- | `Both (c, _) | `Left c | `Right c -> let _ = key in Some c)
- | _ -> cache.text_channels in
- let voice_channels = match C.of_alist !voice with
- | `Ok m ->
- C.merge m cache.voice_channels ~f:(fun ~key -> function
- | `Both (c, _) | `Left c | `Right c -> let _ = key in Some c)
- | _ -> cache.voice_channels in
- let categories = match C.of_alist !cat with
- | `Ok m ->
- C.merge m cache.categories ~f:(fun ~key -> function
- | `Both (c, _) | `Left c | `Right c -> let _ = key in Some c)
- | _ -> cache.categories in
- let users = List.map t.members ~f:(fun m -> m.user.id, m.user) in
- let users = match Cache.UserMap.of_alist users with
- | `Ok m ->
- Cache.UserMap.merge m cache.users ~f:(fun ~key -> function
- | `Both (u, _) | `Left u | `Right u -> let _ = key in Some u)
- | _ -> cache.users in
+ List.iter (function
+ | `GuildText (c:guild_text) -> text := (c.id, c) :: !text
+ | `GuildVoice (c:guild_voice) -> voice := (c.id, c) :: !voice
+ | `Category (c:category) -> cat := (c.id, c) :: !cat
+ | _ -> ()) t.channels;
+ let text_channels =
+ C.of_seq (List.to_seq !text)
+ |> C.merge (fun _ left right -> match (left, right) with
+ | (Some _, Some c) | (Some c, None) | (None, Some c) -> Some c
+ | _ -> None)
+ cache.text_channels in
+ let voice_channels =
+ C.of_seq (List.to_seq !voice)
+ |> C.merge (fun _ left right -> match (left, right) with
+ | (Some _, Some c) | (Some c, None) | (None, Some c) -> Some c
+ | _ -> None)
+ cache.voice_channels in
+ let categories =
+ C.of_seq (List.to_seq !cat)
+ |> C.merge (fun _ left right -> match (left, right) with
+ | (Some _, Some c) | (Some c, None) | (None, Some c) -> Some c
+ | _ -> None)
+ cache.categories in
+ let users = List.map (fun (m:Member_t.t) -> m.user.id, m.user) t.members in
+ let users =
+ Cache.UserMap.of_seq (List.to_seq users)
+ |> Cache.UserMap.merge (fun _ left right -> match (left, right) with
+ | (Some _, Some u) | (Some u, None) | (None, Some u) -> Some u
+ | _ -> None)
+ cache.users in
{ cache with guilds
; unavailable_guilds
; text_channels
@@ -228,24 +238,24 @@ module GuildDelete = struct let module G = Cache.GuildMap in
let module C = Cache.ChannelMap in
if t.unavailable then
- let guilds = G.remove cache.guilds t.id in
- let unavailable_guilds = G.update cache.unavailable_guilds t.id ~f:(function Some _ | None -> t) in
+ let guilds = G.remove t.id cache.guilds in
+ let unavailable_guilds = G.update t.id (function Some _ | None -> Some t) cache.unavailable_guilds in
{ cache with guilds
; unavailable_guilds
}
else
- match G.find cache.guilds t.id with
+ match G.find_opt t.id cache.guilds with
| Some g ->
let text_channels = ref cache.text_channels in
let voice_channels = ref cache.voice_channels in
let categories = ref cache.categories in
- List.iter g.channels ~f:(function
- | `GuildText c -> text_channels := C.remove cache.text_channels c.id
- | `GuildVoice c -> voice_channels := C.remove cache.voice_channels c.id
- | `Category c -> categories := C.remove cache.categories c.id
+ List.iter (function
+ | `GuildText (c:guild_text) -> text_channels := C.remove c.id cache.text_channels
+ | `GuildVoice (c:guild_voice) -> voice_channels := C.remove c.id cache.voice_channels
+ | `Category (c:category) -> categories := C.remove c.id cache.categories
| _ -> ()
- );
- let guilds = G.remove cache.guilds g.id in
+ ) g.channels;
+ let guilds = G.remove g.id cache.guilds in
let text_channels, voice_channels, categories = !text_channels, !voice_channels, !categories in
{ cache with guilds
; text_channels
@@ -253,7 +263,7 @@ module GuildDelete = struct ; categories
}
| None ->
- let guilds = G.remove cache.guilds t.id in
+ let guilds = G.remove t.id cache.guilds in
{ cache with guilds }
end
@@ -266,8 +276,9 @@ module GuildUpdate = struct let update_cache (cache:Cache.t) t =
let open Guild_t in
let {id; _} = t in
- let guilds = Cache.GuildMap.update cache.guilds id ~f:(function
- | Some _ | None -> t) in
+ let guilds = Cache.GuildMap.update id (function
+ | Some _ | None -> Some t)
+ cache.guilds in
{ cache with guilds }
end
@@ -280,12 +291,10 @@ module GuildEmojisUpdate = struct let deserialize = of_yojson_exn
let update_cache (cache:Cache.t) t =
- if Cache.GuildMap.mem cache.guilds t.guild_id then
- let guilds = match Cache.GuildMap.find cache.guilds t.guild_id with
- | Some g -> Cache.GuildMap.set cache.guilds ~key:t.guild_id ~data:{ g with emojis = t.emojis }
- | None -> cache.guilds in
- { cache with guilds }
- else cache
+ let guilds = match Cache.GuildMap.find_opt t.guild_id cache.guilds with
+ | Some g -> Cache.GuildMap.add t.guild_id { g with emojis = t.emojis } cache.guilds
+ | None -> cache.guilds in
+ { cache with guilds }
end
(* TODO guild integrations *)
@@ -296,15 +305,13 @@ module GuildMemberAdd = struct let deserialize = Member_t.of_yojson_exn
let update_cache (cache:Cache.t) (t:t) =
- if Cache.GuildMap.mem cache.guilds t.guild_id then
- let guilds = match Cache.GuildMap.find cache.guilds t.guild_id with
- | Some g ->
- let members = t :: g.members in
- let data = { g with members } in
- Cache.GuildMap.set cache.guilds ~key:t.guild_id ~data
- | None -> cache.guilds in
- { cache with guilds }
- else cache
+ let guilds = match Cache.GuildMap.find_opt t.guild_id cache.guilds with
+ | Some g ->
+ let members = t :: g.members in
+ let data = { g with members } in
+ Cache.GuildMap.add t.guild_id data cache.guilds
+ | None -> cache.guilds in
+ { cache with guilds }
end
module GuildMemberRemove = struct
@@ -316,15 +323,13 @@ module GuildMemberRemove = struct let deserialize = of_yojson_exn
let update_cache (cache:Cache.t) t =
- if Cache.GuildMap.mem cache.guilds t.guild_id then
- let guilds = match Cache.GuildMap.find cache.guilds t.guild_id with
- | Some g ->
- let members = List.filter g.members ~f:(fun m -> m.user.id <> t.user.id) in
- let data = { g with members } in
- Cache.GuildMap.set cache.guilds ~key:t.guild_id ~data
- | None -> cache.guilds in
- { cache with guilds }
- else cache
+ let guilds = match Cache.GuildMap.find_opt t.guild_id cache.guilds with
+ | Some g ->
+ let members = List.filter (fun (m:Member_t.t) -> m.user.id <> t.user.id) g.members in
+ let data = { g with members } in
+ Cache.GuildMap.add t.guild_id data cache.guilds
+ | None -> cache.guilds in
+ { cache with guilds }
end
module GuildMemberUpdate = struct
@@ -338,18 +343,16 @@ module GuildMemberUpdate = struct let deserialize = of_yojson_exn
let update_cache (cache:Cache.t) t =
- if Cache.GuildMap.mem cache.guilds t.guild_id then
- let guilds = match Cache.GuildMap.find cache.guilds t.guild_id with
- | Some g ->
- let members = List.map g.members ~f:(fun m ->
- if m.user.id = t.user.id then
- { m with nick = t.nick; roles = t.roles }
- else m) in
- let data = { g with members } in
- Cache.GuildMap.set cache.guilds ~key:t.guild_id ~data
- | None -> cache.guilds in
- { cache with guilds }
- else cache
+ let guilds = match Cache.GuildMap.find_opt t.guild_id cache.guilds with
+ | Some g ->
+ let members = List.map (fun (m:Member_t.t) ->
+ if m.user.id = t.user.id then
+ { m with nick = t.nick; roles = t.roles }
+ else m) g.members in
+ let data = { g with members } in
+ Cache.GuildMap.add t.guild_id data cache.guilds
+ | None -> cache.guilds in
+ { cache with guilds }
end
module GuildMembersChunk = struct
@@ -361,21 +364,22 @@ module GuildMembersChunk = struct let deserialize = of_yojson_exn
let update_cache (cache:Cache.t) t =
- match Cache.GuildMap.find cache.guilds t.guild_id with
+ match Cache.GuildMap.find_opt t.guild_id cache.guilds with
| None -> cache
| Some g ->
let `Guild_id guild_id = t.guild_id in
- let users = List.map t.members ~f:(fun m -> m.user.id, m.user) in
- let members = List.filter_map t.members ~f:(fun m ->
- if List.exists g.members ~f:(fun m' -> m'.user.id <> m.user.id) then
+ let users = List.map (fun (m:Member_t.member) -> m.user.id, m.user) t.members in
+ let members = Base.List.filter_map ~f:(fun m ->
+ if List.exists (fun (m':Member_t.t) -> m'.user.id <> m.user.id) g.members then
Some (Member_t.wrap ~guild_id m)
- else None) in
- let guilds = Cache.GuildMap.set cache.guilds ~key:t.guild_id ~data:{ g with members } in
- let users = match Cache.UserMap.of_alist users with
- | `Ok m ->
- Cache.UserMap.merge m cache.users ~f:(fun ~key -> function
- | `Both (u, _) | `Left u | `Right u -> let _ = key in Some u)
- | _ -> cache.users in
+ else None) t.members in
+ let guilds = Cache.GuildMap.add t.guild_id { g with members } cache.guilds in
+ let users =
+ Cache.UserMap.of_seq (List.to_seq users)
+ |> Cache.UserMap.merge (fun _ left right -> match (left, right) with
+ | (Some _, Some u) | (Some u, None) | (None, Some u) -> Some u
+ | _ -> None)
+ cache.users in
{ cache with guilds
; users
}
@@ -391,16 +395,14 @@ module GuildRoleCreate = struct let deserialize = of_yojson_exn
let update_cache (cache:Cache.t) t =
- if Cache.GuildMap.mem cache.guilds t.guild_id then
- let guilds = match Cache.GuildMap.find cache.guilds t.guild_id with
- | Some g ->
- let `Guild_id guild_id = t.guild_id in
- let roles = Role_t.wrap ~guild_id t.role :: g.roles in
- let data = { g with roles } in
- Cache.GuildMap.set cache.guilds ~key:t.guild_id ~data
- | None -> cache.guilds in
- { cache with guilds }
- else cache
+ let guilds = match Cache.GuildMap.find_opt t.guild_id cache.guilds with
+ | Some g ->
+ let `Guild_id guild_id = t.guild_id in
+ let roles = Role_t.wrap ~guild_id t.role :: g.roles in
+ let data = { g with roles } in
+ Cache.GuildMap.add t.guild_id data cache.guilds
+ | None -> cache.guilds in
+ { cache with guilds }
end
module GuildRoleDelete = struct
@@ -412,15 +414,13 @@ module GuildRoleDelete = struct let deserialize = of_yojson_exn
let update_cache (cache:Cache.t) t =
- if Cache.GuildMap.mem cache.guilds t.guild_id then
- let guilds = match Cache.GuildMap.find cache.guilds t.guild_id with
- | Some g ->
- let roles = List.filter g.roles ~f:(fun r -> r.id <> t.role_id) in
- let data = { g with roles } in
- Cache.GuildMap.set cache.guilds ~key:t.guild_id ~data
- | None -> cache.guilds in
- { cache with guilds }
- else cache
+ let guilds = match Cache.GuildMap.find_opt t.guild_id cache.guilds with
+ | Some g ->
+ let roles = List.filter (fun (r:Role_t.t) -> r.id <> t.role_id) g.roles in
+ let data = { g with roles } in
+ Cache.GuildMap.add t.guild_id data cache.guilds
+ | None -> cache.guilds in
+ { cache with guilds }
end
module GuildRoleUpdate = struct
@@ -432,17 +432,16 @@ module GuildRoleUpdate = struct let deserialize = of_yojson_exn
let update_cache (cache:Cache.t) t =
- if Cache.GuildMap.mem cache.guilds t.guild_id then
- let guilds = match Cache.GuildMap.find cache.guilds t.guild_id with
- | Some g ->
- let `Guild_id guild_id = t.guild_id in
- let roles = List.map g.roles ~f:(fun r ->
- if r.id = t.role.id then Role_t.wrap ~guild_id t.role else r) in
- let data = { g with roles } in
- Cache.GuildMap.set cache.guilds ~key:t.guild_id ~data
- | None -> cache.guilds in
- { cache with guilds }
- else cache
+ let guilds = match Cache.GuildMap.find_opt t.guild_id cache.guilds with
+ | Some g ->
+ let `Guild_id guild_id = t.guild_id in
+ let roles = List.map (fun (r:Role_t.t) ->
+ if r.id = t.role.id then Role_t.wrap ~guild_id t.role else r)
+ g.roles in
+ let data = { g with roles } in
+ Cache.GuildMap.add t.guild_id data cache.guilds
+ | None -> cache.guilds in
+ { cache with guilds }
end
module MessageCreate = struct
@@ -513,7 +512,7 @@ module PresenceUpdate = struct let update_cache (cache:Cache.t) (t:t) =
let id = t.user.id in
- let presences = Cache.UserMap.update cache.presences id ~f:(function Some _ | None -> t) in
+ let presences = Cache.UserMap.add id t cache.presences in
{ cache with presences }
end
@@ -575,10 +574,13 @@ module Ready = struct let deserialize = of_yojson_exn
let update_cache (cache:Cache.t) t =
- let unavailable_guilds = match List.map t.guilds ~f:(fun g -> g.id, g) |> Cache.GuildMap.of_alist with
- | `Ok m -> Cache.GuildMap.merge m cache.unavailable_guilds ~f:(fun ~key -> function
- | ` Both (g, _) | `Left g | `Right g -> let _ = key in Some g)
- | _ -> cache.unavailable_guilds
+ let unavailable_guilds =
+ List.map (fun (g:Guild_t.unavailable) -> g.id, g) t.guilds
+ |> List.to_seq |> Cache.GuildMap.of_seq
+ |> Cache.GuildMap.merge (fun _ left right -> match (left, right) with
+ | (Some _, Some g) | (Some g, None) | (None, Some g) -> Some g
+ |_ -> None)
+ cache.unavailable_guilds
in
let user = Some t.user in
{ cache with user
diff --git a/lib/models/guild/ban_t.ml b/lib/models/guild/ban_t.ml index 2ebc91d..4afbf73 100644 --- a/lib/models/guild/ban_t.ml +++ b/lib/models/guild/ban_t.ml @@ -1,4 +1,7 @@ -open Core +let string_of_sexp = Base.String.t_of_sexp +let sexp_of_string = Base.String.sexp_of_t +let option_of_sexp = Base.Option.t_of_sexp +let sexp_of_option = Base.Option.sexp_of_t type t = { reason: string option [@default None]; diff --git a/lib/models/guild/guild.ml b/lib/models/guild/guild.ml index 2559df6..70cf2e8 100644 --- a/lib/models/guild/guild.ml +++ b/lib/models/guild/guild.ml @@ -1,12 +1,9 @@ -open Core
-open Async
-
include Guild_t
let ban_user ~id ?(reason="") ?(days=0) guild =
- Http.guild_ban_add (get_id guild) id (`Assoc [
- ("delete-message-days", `Int days);
- ("reason", `String reason);
+ Http.guild_ban_add (get_id guild) id (`Assoc
+ [ "delete-message-days", `Int days
+ ; "reason", `String reason
])
let create data =
@@ -14,10 +11,10 @@ let create data = Http.create_guild data
let create_emoji ~name ~image guild =
- Http.create_emoji (get_id guild) (`Assoc [
- ("name", `String name);
- ("image", `String image);
- ("roles", `List []);
+ Http.create_emoji (get_id guild) (`Assoc
+ [ "name", `String name
+ ; "image", `String image
+ ; "roles", `List []
])
let create_role ~name ?colour ?permissions ?hoist ?mentionable guild =
@@ -41,9 +38,9 @@ let create_channel ~mode ~name guild = | `Text -> 0
| `Voice -> 2
| `Category -> 4
- in Http.create_guild_channel (get_id guild) (`Assoc [
- ("name", `String name);
- ("type", `Int kind);
+ in Http.create_guild_channel (get_id guild) (`Assoc
+ [ "name", `String name
+ ; "type", `Int kind
])
let delete guild =
@@ -71,7 +68,7 @@ let get_webhooks guild = let kick_user ~id ?reason guild =
let payload = match reason with
- | Some r -> `Assoc [("reason", `String r)]
+ | Some r -> `Assoc ["reason", `String r]
| None -> `Null
in Http.remove_member (get_id guild) id payload
@@ -88,21 +85,13 @@ let prune ~days guild = let request_members guild =
Http.get_members (get_id guild)
-let set_afk_channel ~id guild = Http.edit_guild (get_id guild) (`Assoc [
- ("afk_channel_id", `Int id);
- ])
+let set_afk_channel ~id guild = Http.edit_guild (get_id guild) (`Assoc [ "afk_channel_id", `Int id ])
-let set_afk_timeout ~timeout guild = Http.edit_guild (get_id guild) (`Assoc [
- ("afk_timeout", `Int timeout);
- ])
+let set_afk_timeout ~timeout guild = Http.edit_guild (get_id guild) (`Assoc [ "afk_timeout", `Int timeout ])
-let set_name ~name guild = Http.edit_guild (get_id guild) (`Assoc [
- ("name", `String name);
- ])
+let set_name ~name guild = Http.edit_guild (get_id guild) (`Assoc [ "name", `String name ])
-let set_icon ~icon guild = Http.edit_guild (get_id guild) (`Assoc [
- ("icon", `String icon);
- ])
+let set_icon ~icon guild = Http.edit_guild (get_id guild) (`Assoc [ "icon", `String icon ])
let unban_user ~id ?reason guild =
let payload = match reason with
@@ -111,18 +100,18 @@ let unban_user ~id ?reason guild = in Http.guild_ban_remove (get_id guild) id payload
let get_member ~(id:User_id_t.t) guild =
- match List.find ~f:(fun m -> m.user.id = id) guild.members with
- | Some m -> Deferred.Or_error.return m
+ match List.find_opt (fun (m:Member_t.t) -> m.user.id = id) guild.members with
+ | Some m -> Lwt_result.return m
| None ->
let `User_id id = id in
Http.get_member (get_id guild) id
let get_channel ~(id:Channel_id_t.t) guild =
let `Channel_id id = id in
- match List.find ~f:(fun c -> Channel_t.get_id c = id) guild.channels with
- | Some c -> Deferred.Or_error.return c
+ match List.find_opt (fun c -> Channel_t.get_id c = id) guild.channels with
+ | Some c -> Lwt_result.return c
| None -> Http.get_channel id
(* TODO add HTTP fallback *)
let get_role ~(id:Role_id.t) guild =
- List.find ~f:(fun r -> r.id = id) guild.roles
+ List.find_opt (fun (r:Role_t.t) -> r.id = id) guild.roles
diff --git a/lib/models/guild/guild.mli b/lib/models/guild/guild.mli index 1fbcf55..90640d7 100644 --- a/lib/models/guild/guild.mli +++ b/lib/models/guild/guild.mli @@ -1,10 +1,8 @@ -open Async
-
include module type of Guild_t
-val ban_user : id:Snowflake.t -> ?reason:string -> ?days:int -> t -> unit Deferred.Or_error.t
-val create : (string * Yojson.Safe.t) list -> t Deferred.Or_error.t
-val create_emoji : name:string -> image:string -> t -> Emoji.t Deferred.Or_error.t
+val ban_user : id:Snowflake.t -> ?reason:string -> ?days:int -> t -> (unit, string) Lwt_result.t
+val create : (string * Yojson.Safe.t) list -> (t, string) Lwt_result.t
+val create_emoji : name:string -> image:string -> t -> (Emoji.t, string) Lwt_result.t
val create_role :
name:string ->
?colour:int ->
@@ -12,31 +10,31 @@ val create_role : ?hoist:bool ->
?mentionable:bool ->
t ->
- Role_t.t Deferred.Or_error.t
-val create_channel : mode:[ `Text | `Voice | `Category ] -> name:string -> t -> Channel_t.t Deferred.Or_error.t
-val delete : t -> unit Deferred.Or_error.t
-val get_ban : id:Snowflake.t -> t -> Ban_t.t Deferred.Or_error.t
-val get_bans : t -> Ban_t.t list Deferred.Or_error.t
-val get_emoji : id:Snowflake.t -> t -> Emoji.t Deferred.Or_error.t
-val get_invites : t -> Yojson.Safe.t Deferred.Or_error.t
-val get_prune_count : days:int -> t -> int Deferred.Or_error.t
-val get_webhooks : t -> Yojson.Safe.t Deferred.Or_error.t
-val kick_user : id:Snowflake.t -> ?reason:string -> t -> unit Deferred.Or_error.t
-val leave : t -> unit Deferred.Or_error.t
-val list_voice_regions : t -> Yojson.Safe.t Deferred.Or_error.t
-val prune : days:int -> t -> int Deferred.Or_error.t
-val request_members : t -> Member_t.t list Deferred.Or_error.t
-val set_afk_channel : id:Snowflake.t -> t -> Guild_t.t Deferred.Or_error.t
-val set_afk_timeout : timeout:int -> t -> Guild_t.t Deferred.Or_error.t
-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
+ (Role_t.t, string) Lwt_result.t
+val create_channel : mode:[ `Text | `Voice | `Category ] -> name:string -> t -> (Channel_t.t, string) Lwt_result.t
+val delete : t -> (unit, string) Lwt_result.t
+val get_ban : id:Snowflake.t -> t -> (Ban_t.t, string) Lwt_result.t
+val get_bans : t -> (Ban_t.t list, string) Lwt_result.t
+val get_emoji : id:Snowflake.t -> t -> (Emoji.t, string) Lwt_result.t
+val get_invites : t -> (Yojson.Safe.t, string) Lwt_result.t
+val get_prune_count : days:int -> t -> (int, string) Lwt_result.t
+val get_webhooks : t -> (Yojson.Safe.t, string) Lwt_result.t
+val kick_user : id:Snowflake.t -> ?reason:string -> t -> (unit, string) Lwt_result.t
+val leave : t -> (unit, string) Lwt_result.t
+val list_voice_regions : t -> (Yojson.Safe.t, string) Lwt_result.t
+val prune : days:int -> t -> (int, string) Lwt_result.t
+val request_members : t -> (Member_t.t list, string) Lwt_result.t
+val set_afk_channel : id:Snowflake.t -> t -> (Guild_t.t, string) Lwt_result.t
+val set_afk_timeout : timeout:int -> t -> (Guild_t.t, string) Lwt_result.t
+val set_name : name:string -> t -> (Guild_t.t, string) Lwt_result.t
+val set_icon : icon:string -> t -> (Guild_t.t, string) Lwt_result.t
+val unban_user : id:Snowflake.t -> ?reason:string -> t -> (unit, string) Lwt_result.t
(** Get a channel belonging to this guild. This does not make an HTTP request. *)
-val get_channel : id:Channel_id_t.t -> t -> Channel_t.t Deferred.Or_error.t
+val get_channel : id:Channel_id_t.t -> t -> (Channel_t.t, string) Lwt_result.t
(** Get a member belonging to this guild. This does not make an HTTP request. *)
-val get_member : id:User_id_t.t -> t -> Member_t.t Deferred.Or_error.t
+val get_member : id:User_id_t.t -> t -> (Member_t.t, string) Lwt_result.t
(** Get a role belonging to this guild. This does not make an HTTP request. *)
val get_role : id:Role_id.t -> t -> Role_t.t option
\ No newline at end of file diff --git a/lib/models/guild/guild_t.ml b/lib/models/guild/guild_t.ml index afe3d19..b486429 100644 --- a/lib/models/guild/guild_t.ml +++ b/lib/models/guild/guild_t.ml @@ -1,4 +1,13 @@ -open Core
+let string_of_sexp = Base.String.t_of_sexp
+let sexp_of_string = Base.String.sexp_of_t
+let option_of_sexp = Base.Option.t_of_sexp
+let sexp_of_option = Base.Option.sexp_of_t
+let int_of_sexp = Base.Int.t_of_sexp
+let sexp_of_int = Base.Int.sexp_of_t
+let bool_of_sexp = Base.Bool.t_of_sexp
+let sexp_of_bool = Base.Bool.sexp_of_t
+let list_of_sexp = Base.List.t_of_sexp
+let sexp_of_list = Base.List.sexp_of_t
type unavailable = {
id: Guild_id_t.t;
@@ -63,9 +72,9 @@ type t = { let wrap ({id;name;icon;splash;owner_id;region;afk_channel_id;afk_timeout;embed_enabled;embed_channel_id;verification_level;default_message_notifications;explicit_content_filter;roles;emojis;features;mfa_level;application_id;widget_enabled;widget_channel_id;system_channel_id;large;member_count;members;channels}:pre) =
let `Guild_id id = id in
- let roles = List.map ~f:(Role_t.wrap ~guild_id:id) roles in
- let members = List.map ~f:(Member_t.wrap ~guild_id:id) members in
- let channels = List.map ~f:Channel_t.wrap channels in
+ let roles = List.map (Role_t.wrap ~guild_id:id) roles in
+ let members = List.map (Member_t.wrap ~guild_id:id) members in
+ let channels = List.map Channel_t.wrap channels in
{id = `Guild_id id;name;icon;splash;owner_id;region;afk_channel_id;afk_timeout;embed_enabled;embed_channel_id;verification_level;default_message_notifications;explicit_content_filter;roles;emojis;features;mfa_level;application_id;widget_enabled;widget_channel_id;system_channel_id;large;member_count;members;channels}
let get_id guild = let `Guild_id id = guild.id in id
\ No newline at end of file diff --git a/lib/models/guild/member.mli b/lib/models/guild/member.mli index a3acc1b..76cb2de 100644 --- a/lib/models/guild/member.mli +++ b/lib/models/guild/member.mli @@ -1,27 +1,25 @@ -open Async - include module type of Member_t (** Adds a role to the member. *) -val add_role : role:Role_t.t -> Member_t.t -> unit Deferred.Or_error.t +val add_role : role:Role_t.t -> Member_t.t -> (unit, string) Lwt_result.t (** Removes a role from the member. *) -val remove_role : role:Role_t.t -> Member_t.t -> unit Deferred.Or_error.t +val remove_role : role:Role_t.t -> Member_t.t -> (unit, string) Lwt_result.t (** Bans the member with optional reason and days of messages to delete. *) -val ban : ?reason:string -> ?days:int -> Member_t.t -> unit Deferred.Or_error.t +val ban : ?reason:string -> ?days:int -> Member_t.t -> (unit, string) Lwt_result.t (** Kicks the member with the optional reason. *) -val kick : ?reason:string -> Member_t.t -> unit Deferred.Or_error.t +val kick : ?reason:string -> Member_t.t -> (unit, string) Lwt_result.t (** Mutes the member, preventing them from speaking in voice chats. *) -val mute : Member_t.t -> unit Deferred.Or_error.t +val mute : Member_t.t -> (unit, string) Lwt_result.t (** Deafens the member, preventing them from hearing others in voice chats. *) -val deafen : Member_t.t -> unit Deferred.Or_error.t +val deafen : Member_t.t -> (unit, string) Lwt_result.t (** Opposite of {!mute}. *) -val unmute : Member_t.t -> unit Deferred.Or_error.t +val unmute : Member_t.t -> (unit, string) Lwt_result.t (** Opposite of {!deafen}. *) -val undeafen : Member_t.t -> unit Deferred.Or_error.t
\ No newline at end of file +val undeafen : Member_t.t -> (unit, string) Lwt_result.t
\ No newline at end of file diff --git a/lib/models/guild/member_t.ml b/lib/models/guild/member_t.ml index 4e01b9a..8e15284 100644 --- a/lib/models/guild/member_t.ml +++ b/lib/models/guild/member_t.ml @@ -1,4 +1,11 @@ -open Core
+let string_of_sexp = Base.String.t_of_sexp
+let sexp_of_string = Base.String.sexp_of_t
+let option_of_sexp = Base.Option.t_of_sexp
+let sexp_of_option = Base.Option.sexp_of_t
+let bool_of_sexp = Base.Bool.t_of_sexp
+let sexp_of_bool = Base.Bool.sexp_of_t
+let list_of_sexp = Base.List.t_of_sexp
+let sexp_of_list = Base.List.sexp_of_t
type partial_member = {
nick: string option [@default None];
diff --git a/lib/models/guild/role.mli b/lib/models/guild/role.mli index b311a60..70474a6 100644 --- a/lib/models/guild/role.mli +++ b/lib/models/guild/role.mli @@ -1,24 +1,22 @@ -open Async - include module type of Role_t (** Deletes the role. This is permanent. *) -val delete : t -> unit Deferred.Or_error.t +val delete : t -> (unit, string) Lwt_result.t (** Edits the role to allow mentions. *) -val allow_mention : t -> t Deferred.Or_error.t +val allow_mention : t -> (t, string) Lwt_result.t (** Opposite of {!allow_mention} *) -val disallow_mention : t -> t Deferred.Or_error.t +val disallow_mention : t -> (t, string) Lwt_result.t (** Hoists the role. See {!Role.t.hoist}. *) -val hoist : t -> t Deferred.Or_error.t +val hoist : t -> (t, string) Lwt_result.t (** Opposite of {!hoist}. *) -val unhoist : t -> t Deferred.Or_error.t +val unhoist : t -> (t, string) Lwt_result.t (** Sets the colour of the role. *) -val set_colour : colour:int -> t -> t Deferred.Or_error.t +val set_colour : colour:int -> t -> (t, string) Lwt_result.t (** Sets the name of the role. *) -val set_name : name:string -> t -> t Deferred.Or_error.t +val set_name : name:string -> t -> (t, string) Lwt_result.t diff --git a/lib/models/guild/role_t.ml b/lib/models/guild/role_t.ml index 2927c20..a28f84f 100644 --- a/lib/models/guild/role_t.ml +++ b/lib/models/guild/role_t.ml @@ -1,4 +1,9 @@ -open Core
+let string_of_sexp = Base.String.t_of_sexp
+let sexp_of_string = Base.String.sexp_of_t
+let int_of_sexp = Base.Int.t_of_sexp
+let sexp_of_int = Base.Int.sexp_of_t
+let bool_of_sexp = Base.Bool.t_of_sexp
+let sexp_of_bool = Base.Bool.sexp_of_t
type role = {
id: Role_id.t;
diff --git a/lib/models/id/channel_id.ml b/lib/models/id/channel_id.ml index 1017ad1..a147e86 100644 --- a/lib/models/id/channel_id.ml +++ b/lib/models/id/channel_id.ml @@ -1,4 +1,3 @@ -open Core
include Channel_id_t
exception Invalid_message
@@ -51,5 +50,5 @@ let get_pins ch = Http.get_pinned_messages (get_id ch)
let bulk_delete msgs ch =
- let msgs = `List (List.map ~f:(fun id -> `Int id) msgs) in
+ let msgs = `List (List.map (fun id -> `Int id) msgs) in
Http.bulk_delete (get_id ch) msgs
\ No newline at end of file diff --git a/lib/models/id/channel_id.mli b/lib/models/id/channel_id.mli index 74010a5..fd884a4 100644 --- a/lib/models/id/channel_id.mli +++ b/lib/models/id/channel_id.mli @@ -1,4 +1,3 @@ -open Async
include module type of Channel_id_t
exception Invalid_message
@@ -27,20 +26,20 @@ val send_message : ?file:string ->
?tts:bool ->
t ->
- Message_t.t Deferred.Or_error.t
+ (Message_t.t, string) Lwt_result.t
(** [say str ch] is equivalent to [send_message ~content:str ch]. *)
-val say : string -> t -> Message_t.t Deferred.Or_error.t
+val say : string -> t -> (Message_t.t, string) Lwt_result.t
-val delete : t -> Channel_t.t Deferred.Or_error.t
-val get_message : id:Snowflake.t -> t -> Message_t.t Deferred.Or_error.t
+val delete : t -> (Channel_t.t, string) Lwt_result.t
+val get_message : id:Snowflake.t -> t -> (Message_t.t, string) Lwt_result.t
val get_messages :
?mode:[ `Before | `After | `Around ] ->
?id:Snowflake.t ->
?limit:int ->
t ->
- Message_t.t list Deferred.Or_error.t
-val broadcast_typing : t -> unit Deferred.Or_error.t
-val get_pins : t -> Message_t.t list Deferred.Or_error.t
-val bulk_delete : Snowflake.t list -> t -> unit Deferred.Or_error.t
+ (Message_t.t list, string) Lwt_result.t
+val broadcast_typing : t -> (unit, string) Lwt_result.t
+val get_pins : t -> (Message_t.t list, string) Lwt_result.t
+val bulk_delete : Snowflake.t list -> t -> (unit, string) Lwt_result.t
(* TODO more things related to guild channels *)
diff --git a/lib/models/id/channel_id_t.ml b/lib/models/id/channel_id_t.ml index cea85e0..c28a749 100644 --- a/lib/models/id/channel_id_t.ml +++ b/lib/models/id/channel_id_t.ml @@ -1,8 +1,6 @@ -open Core
-
type t = [ `Channel_id of Snowflake.t ] [@@deriving sexp]
-let compare (`Channel_id t) (`Channel_id t') = Int.compare t t'
+let compare (`Channel_id t) (`Channel_id t') = Base.Int.compare t t'
let of_yojson a : (t, string) result =
match Snowflake.of_yojson a with
diff --git a/lib/models/id/guild_id.mli b/lib/models/id/guild_id.mli index 11f34f7..9f88cef 100644 --- a/lib/models/id/guild_id.mli +++ b/lib/models/id/guild_id.mli @@ -1,8 +1,7 @@ -open Async
include module type of Guild_id_t
-val ban_user : id:Snowflake.t -> ?reason:string -> ?days:int -> t -> unit Deferred.Or_error.t
-val create_emoji : name:string -> image:string -> t -> Emoji.t Deferred.Or_error.t
+val ban_user : id:Snowflake.t -> ?reason:string -> ?days:int -> t -> (unit, string) Lwt_result.t
+val create_emoji : name:string -> image:string -> t -> (Emoji.t, string) Lwt_result.t
val create_role :
name:string ->
?colour:int ->
@@ -10,22 +9,22 @@ val create_role : ?hoist:bool ->
?mentionable:bool ->
t ->
- Role_t.t Deferred.Or_error.t
-val create_channel : mode:[ `Text | `Voice | `Category ] -> name:string -> t -> Channel_t.t Deferred.Or_error.t
-val delete : t -> unit Deferred.Or_error.t
-val get_ban : id:Snowflake.t -> t -> Ban_t.t Deferred.Or_error.t
-val get_bans : t -> Ban_t.t list Deferred.Or_error.t
-val get_emoji : id:Snowflake.t -> t -> Emoji.t Deferred.Or_error.t
-val get_invites : t -> Yojson.Safe.t Deferred.Or_error.t
-val get_prune_count : days:int -> t -> int Deferred.Or_error.t
-val get_webhooks : t -> Yojson.Safe.t Deferred.Or_error.t
-val kick_user : id:Snowflake.t -> ?reason:string -> t -> unit Deferred.Or_error.t
-val leave : t -> unit Deferred.Or_error.t
-val list_voice_regions : t -> Yojson.Safe.t Deferred.Or_error.t
-val prune : days:int -> t -> int Deferred.Or_error.t
-val request_members : t -> Member_t.t list Deferred.Or_error.t
-val set_afk_channel : id:Snowflake.t -> t -> Guild_t.t Deferred.Or_error.t
-val set_afk_timeout : timeout:int -> t -> Guild_t.t Deferred.Or_error.t
-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
\ No newline at end of file + (Role_t.t, string) Lwt_result.t
+val create_channel : mode:[ `Text | `Voice | `Category ] -> name:string -> t -> (Channel_t.t, string) Lwt_result.t
+val delete : t -> (unit, string) Lwt_result.t
+val get_ban : id:Snowflake.t -> t -> (Ban_t.t, string) Lwt_result.t
+val get_bans : t -> (Ban_t.t list, string) Lwt_result.t
+val get_emoji : id:Snowflake.t -> t -> (Emoji.t, string) Lwt_result.t
+val get_invites : t -> (Yojson.Safe.t, string) Lwt_result.t
+val get_prune_count : days:int -> t -> (int, string) Lwt_result.t
+val get_webhooks : t -> (Yojson.Safe.t, string) Lwt_result.t
+val kick_user : id:Snowflake.t -> ?reason:string -> t -> (unit, string) Lwt_result.t
+val leave : t -> (unit, string) Lwt_result.t
+val list_voice_regions : t -> (Yojson.Safe.t, string) Lwt_result.t
+val prune : days:int -> t -> (int, string) Lwt_result.t
+val request_members : t -> (Member_t.t list, string) Lwt_result.t
+val set_afk_channel : id:Snowflake.t -> t -> (Guild_t.t, string) Lwt_result.t
+val set_afk_timeout : timeout:int -> t -> (Guild_t.t, string) Lwt_result.t
+val set_name : name:string -> t -> (Guild_t.t, string) Lwt_result.t
+val set_icon : icon:string -> t -> (Guild_t.t, string) Lwt_result.t
+val unban_user : id:Snowflake.t -> ?reason:string -> t -> (unit, string) Lwt_result.t
\ No newline at end of file diff --git a/lib/models/id/guild_id_t.ml b/lib/models/id/guild_id_t.ml index a39c07d..6d92045 100644 --- a/lib/models/id/guild_id_t.ml +++ b/lib/models/id/guild_id_t.ml @@ -1,8 +1,6 @@ -open Core
-
type t = [ `Guild_id of Snowflake.t ] [@@deriving sexp]
-let compare (`Guild_id t) (`Guild_id t') = Int.compare t t'
+let compare (`Guild_id t) (`Guild_id t') = Base.Int.compare t t'
let of_yojson a : (t, string) result =
match Snowflake.of_yojson a with
diff --git a/lib/models/id/message_id.ml b/lib/models/id/message_id.ml index 3c45e16..10bcb1d 100644 --- a/lib/models/id/message_id.ml +++ b/lib/models/id/message_id.ml @@ -1,5 +1,3 @@ -open Core
-
type t = [ `Message_id of Snowflake.t ] [@@deriving sexp]
let of_yojson a : (t, string) result =
diff --git a/lib/models/id/role_id.ml b/lib/models/id/role_id.ml index 0bbf8be..f055b1a 100644 --- a/lib/models/id/role_id.ml +++ b/lib/models/id/role_id.ml @@ -1,5 +1,3 @@ -open Core
-
type t = [ `Role_id of Snowflake.t ] [@@deriving sexp]
let of_yojson a : (t, string) result =
diff --git a/lib/models/id/user_id_t.ml b/lib/models/id/user_id_t.ml index cf1634a..0c7f3b3 100644 --- a/lib/models/id/user_id_t.ml +++ b/lib/models/id/user_id_t.ml @@ -1,8 +1,6 @@ -open Core
-
type t = [ `User_id of Snowflake.t ] [@@deriving sexp]
-let compare (`User_id t) (`User_id t') = Int.compare t t'
+let compare (`User_id t) (`User_id t') = Base.Int.compare t t'
let of_yojson a : (t, string) result =
match Snowflake.of_yojson a with
diff --git a/lib/models/overwrites.ml b/lib/models/overwrites.ml index 4603c91..6e015dc 100644 --- a/lib/models/overwrites.ml +++ b/lib/models/overwrites.ml @@ -1,4 +1,5 @@ -open Core +let string_of_sexp = Base.String.t_of_sexp +let sexp_of_string = Base.String.sexp_of_t type t = { id: Snowflake.t diff --git a/lib/models/permissions.ml b/lib/models/permissions.ml index 7a0892b..7a21f61 100644 --- a/lib/models/permissions.ml +++ b/lib/models/permissions.ml @@ -36,8 +36,8 @@ include BitMaskSet.Make(struct let mask = 0b0111_1111_1111_0111_1111_1101_1111_1111 end) -let sexp_of_t = Core.Int.sexp_of_t -let t_of_sexp = Core.Int.t_of_sexp +let sexp_of_t = Base.Int.sexp_of_t +let t_of_sexp = Base.Int.t_of_sexp let of_yojson_exn j = create @@ Yojson.Safe.Util.to_int j diff --git a/lib/models/snowflake.ml b/lib/models/snowflake.ml index 2bf2281..68b5c6a 100644 --- a/lib/models/snowflake.ml +++ b/lib/models/snowflake.ml @@ -1,4 +1,4 @@ -open Core
+module Int = Base.Int
type t = Int.t [@@deriving sexp]
@@ -12,11 +12,11 @@ let to_yojson s : Yojson.Safe.t = `String (Int.to_string s) let timestamp snowflake = (snowflake lsr 22) + 1_420_070_400_000
-let time_of_t snowflake =
+(* let time_of_t snowflake =
let t = timestamp snowflake |> float_of_int in
Time.(Span.of_ms t
|> of_span_since_epoch)
let timestamp_iso snowflake =
time_of_t snowflake
- |> Time.(to_string_iso8601_basic ~zone:Zone.utc)
\ No newline at end of file + |> Time.(to_string_iso8601_basic ~zone:Zone.utc) *)
\ No newline at end of file diff --git a/lib/models/snowflake.mli b/lib/models/snowflake.mli index 0c42e4a..1f3622c 100644 --- a/lib/models/snowflake.mli +++ b/lib/models/snowflake.mli @@ -1,12 +1,10 @@ -open Core
-
-type t = Int.t [@@deriving sexp, yojson { exn = true }]
+type t = Base.Int.t [@@deriving sexp, yojson { exn = true }]
(** Convert a snowflake into a {!Core.Time.t} *)
-val time_of_t : t -> Time.t
+(* val time_of_t : t -> Time.t *)
(** Convert a snowflake into a Unix timestamp. Millisecond precision. *)
val timestamp : t -> int
(** Convert a snowflake into an ISO8601 timestamp string. This is equivalent to calling [Snowflake.time_of_t snowflake |> Time.(to_string_iso8601_basic ~zone:Zone.utc)] *)
-val timestamp_iso : t -> string
\ No newline at end of file +(* val timestamp_iso : t -> string *)
\ No newline at end of file diff --git a/lib/models/user/activity.ml b/lib/models/user/activity.ml index 926c899..70706e7 100644 --- a/lib/models/user/activity.ml +++ b/lib/models/user/activity.ml @@ -1,4 +1,9 @@ -open Core +let string_of_sexp = Base.String.t_of_sexp +let sexp_of_string = Base.String.sexp_of_t +let option_of_sexp = Base.Option.t_of_sexp +let sexp_of_option = Base.Option.sexp_of_t +let int_of_sexp = Base.Int.t_of_sexp +let sexp_of_int = Base.Int.sexp_of_t type t = { name: string; diff --git a/lib/models/user/presence.ml b/lib/models/user/presence.ml index d8683b7..ba076fa 100644 --- a/lib/models/user/presence.ml +++ b/lib/models/user/presence.ml @@ -1,4 +1,9 @@ -open Core +let string_of_sexp = Base.String.t_of_sexp +let sexp_of_string = Base.String.sexp_of_t +let option_of_sexp = Base.Option.t_of_sexp +let sexp_of_option = Base.Option.sexp_of_t +let list_of_sexp = Base.List.t_of_sexp +let sexp_of_list = Base.List.sexp_of_t type t = { user: User_t.partial_user; diff --git a/lib/models/user/user.ml b/lib/models/user/user.ml index b8c3b25..4df2f1c 100644 --- a/lib/models/user/user.ml +++ b/lib/models/user/user.ml @@ -1,4 +1,3 @@ -open Core
include User_t
let tag user =
@@ -9,14 +8,14 @@ let mention user = Printf.sprintf "<@%d>" id
let default_avatar user =
- let avatar = Int.of_string user.discriminator % 5 in
+ let avatar = int_of_string user.discriminator mod 5 in
Endpoints.cdn_default_avatar avatar
let face user =
let `User_id id = user.id in
match user.avatar with
| Some avatar ->
- let ext = if String.is_substring ~substring:"a_" avatar
+ let ext = if Base.String.is_substring ~substring:"a_" avatar
then "gif"
else "png" in
Endpoints.cdn_avatar id avatar ext
diff --git a/lib/models/user/user_t.ml b/lib/models/user/user_t.ml index b68808d..44f33fe 100644 --- a/lib/models/user/user_t.ml +++ b/lib/models/user/user_t.ml @@ -1,4 +1,9 @@ -open Core
+let string_of_sexp = Base.String.t_of_sexp
+let sexp_of_string = Base.String.sexp_of_t
+let option_of_sexp = Base.Option.t_of_sexp
+let sexp_of_option = Base.Option.sexp_of_t
+let bool_of_sexp = Base.Bool.t_of_sexp
+let sexp_of_bool = Base.Bool.sexp_of_t
type partial_user = {
id: User_id_t.t;
|