Skip to content

Commit

Permalink
Add module type CLIENT
Browse files Browse the repository at this point in the history
This module type is implemented by Irc_client_lwt, Irc_client_unix and
Irc_client_tls.

Signed-off-by: John Else <john.else@gmail.com>
  • Loading branch information
johnelse committed Jan 3, 2017
1 parent 8c580b0 commit 364253a
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 110 deletions.
105 changes: 105 additions & 0 deletions lib/irc_client.ml
Original file line number Diff line number Diff line change
@@ -1,4 +1,109 @@
module type CLIENT = sig
module Io : sig
type 'a t
type inet_addr
type config
end

type connection_t

val send : connection:connection_t -> Irc_message.t -> unit Io.t
(** Send the given message *)

val send_join : connection:connection_t -> channel:string -> unit Io.t
(** Send the JOIN command. *)

val send_nick : connection:connection_t -> nick:string -> unit Io.t
(** Send the NICK command. *)

val send_pass : connection:connection_t -> password:string -> unit Io.t
(** Send the PASS command. *)

val send_pong : connection:connection_t -> message:string -> unit Io.t
(** Send the PONG command. *)

val send_privmsg : connection:connection_t ->
target:string -> message:string -> unit Io.t
(** Send the PRIVMSG command. *)

val send_notice : connection:connection_t ->
target:string -> message:string -> unit Io.t
(** Send the NOTICE command. *)

val send_quit : connection:connection_t -> unit Io.t
(** Send the QUIT command. *)

val send_user : connection:connection_t ->
username:string -> mode:int -> realname:string -> unit Io.t
(** Send the USER command. *)

val connect :
?username:string -> ?mode:int -> ?realname:string -> ?password:string ->
?config:Io.config ->
addr:Io.inet_addr -> port:int -> nick:string -> unit ->
connection_t Io.t
(** Connect to an IRC server at address [addr]. The PASS command will be
sent if [password] is not None. *)

val connect_by_name :
?username:string -> ?mode:int -> ?realname:string -> ?password:string ->
server:string -> port:int -> nick:string -> unit ->
connection_t option Io.t
(** Try to resolve the [server] name using DNS, otherwise behaves like
{!connect}. Returns [None] if no IP could be found for the given
name. *)

(** Information on keeping the connection alive *)
type keepalive = {
mode: [`Active | `Passive];
timeout: int;
}

val default_keepalive : keepalive
(** Default value for keepalive: active mode with auto-reconnect *)

val listen :
?keepalive:keepalive ->
connection:connection_t ->
callback:(
connection_t ->
Irc_message.parse_result ->
unit Io.t) ->
unit ->
unit Io.t
(** [listen connection callback] listens for incoming messages on
[connection]. All server pings are handled internally; all other
messages are passed, along with [connection], to [callback].
@param keepalive the behavior on disconnection (if the transport
supports {!Irc_transport.IO.pick} and {!Irc_transport.IO.sleep}) *)

val reconnect_loop :
?keepalive:keepalive ->
after:int ->
connect:(unit -> connection_t option Io.t) ->
f:(connection_t -> unit Io.t) ->
callback:(
connection_t ->
Irc_message.parse_result ->
unit Io.t) ->
unit ->
unit Io.t
(** A combination of {!connect} and {!listen} that, every time
the connection is terminated, tries to start a new one
after [after] seconds.
@param after time before trying to reconnect
@param connect how to reconnect
(a closure over {!connect} or {!connect_by_name})
@param callback the callback for {!listen}
@param f the function to call after connection *)

val set_log : (string -> unit Io.t) -> unit
(** Set logging function *)
end

module Make(Io: Irc_transport.IO) = struct
module Io = Io

type connection_t = {
sock: Io.file_descr;
buffer: Buffer.t;
Expand Down
203 changes: 106 additions & 97 deletions lib/irc_client.mli
Original file line number Diff line number Diff line change
@@ -1,101 +1,110 @@
(** Generic IRC client library, functorised over the
{{:Irc_transport.IO.html}Irc_transport.IO} module. *)

module Make : functor (Io: Irc_transport.IO) ->
sig
type connection_t
(** A connection to an IRC server. *)

val send : connection:connection_t -> Irc_message.t -> unit Io.t
(** Send the given message *)

val send_join : connection:connection_t -> channel:string -> unit Io.t
(** Send the JOIN command. *)

val send_nick : connection:connection_t -> nick:string -> unit Io.t
(** Send the NICK command. *)

val send_pass : connection:connection_t -> password:string -> unit Io.t
(** Send the PASS command. *)

val send_pong : connection:connection_t -> message:string -> unit Io.t
(** Send the PONG command. *)

val send_privmsg : connection:connection_t ->
target:string -> message:string -> unit Io.t
(** Send the PRIVMSG command. *)

val send_notice : connection:connection_t ->
target:string -> message:string -> unit Io.t
(** Send the NOTICE command. *)

val send_quit : connection:connection_t -> unit Io.t
(** Send the QUIT command. *)

val send_user : connection:connection_t ->
username:string -> mode:int -> realname:string -> unit Io.t
(** Send the USER command. *)

val connect :
?username:string -> ?mode:int -> ?realname:string -> ?password:string ->
?config:Io.config ->
addr:Io.inet_addr -> port:int -> nick:string -> unit ->
connection_t Io.t
(** Connect to an IRC server at address [addr]. The PASS command will be
sent if [password] is not None. *)

val connect_by_name :
?username:string -> ?mode:int -> ?realname:string -> ?password:string ->
server:string -> port:int -> nick:string -> unit ->
connection_t option Io.t
(** Try to resolve the [server] name using DNS, otherwise behaves like
{!connect}. Returns [None] if no IP could be found for the given
name. *)

(** Information on keeping the connection alive *)
type keepalive = {
mode: [`Active | `Passive];
timeout: int;
}

val default_keepalive : keepalive
(** Default value for keepalive: active mode with auto-reconnect *)

val listen :
?keepalive:keepalive ->
connection:connection_t ->
callback:(
connection_t ->
Irc_message.parse_result ->
unit Io.t) ->
unit ->
unit Io.t
(** [listen connection callback] listens for incoming messages on
[connection]. All server pings are handled internally; all other
messages are passed, along with [connection], to [callback].
@param keepalive the behavior on disconnection (if the transport
supports {!Irc_transport.IO.pick} and {!Irc_transport.IO.sleep}) *)

val reconnect_loop :
?keepalive:keepalive ->
after:int ->
connect:(unit -> connection_t option Io.t) ->
f:(connection_t -> unit Io.t) ->
callback:(
connection_t ->
Irc_message.parse_result ->
unit Io.t) ->
unit ->
unit Io.t
(** A combination of {!connect} and {!listen} that, every time
the connection is terminated, tries to start a new one
after [after] seconds.
@param after time before trying to reconnect
@param connect how to reconnect
(a closure over {!connect} or {!connect_by_name})
@param callback the callback for {!listen}
@param f the function to call after connection *)

val set_log : (string -> unit Io.t) -> unit
(** Set logging function *)
module type CLIENT = sig
module Io : sig
type 'a t
type inet_addr
type config
end

type connection_t

val send : connection:connection_t -> Irc_message.t -> unit Io.t
(** Send the given message *)

val send_join : connection:connection_t -> channel:string -> unit Io.t
(** Send the JOIN command. *)

val send_nick : connection:connection_t -> nick:string -> unit Io.t
(** Send the NICK command. *)

val send_pass : connection:connection_t -> password:string -> unit Io.t
(** Send the PASS command. *)

val send_pong : connection:connection_t -> message:string -> unit Io.t
(** Send the PONG command. *)

val send_privmsg : connection:connection_t ->
target:string -> message:string -> unit Io.t
(** Send the PRIVMSG command. *)

val send_notice : connection:connection_t ->
target:string -> message:string -> unit Io.t
(** Send the NOTICE command. *)

val send_quit : connection:connection_t -> unit Io.t
(** Send the QUIT command. *)

val send_user : connection:connection_t ->
username:string -> mode:int -> realname:string -> unit Io.t
(** Send the USER command. *)

val connect :
?username:string -> ?mode:int -> ?realname:string -> ?password:string ->
?config:Io.config ->
addr:Io.inet_addr -> port:int -> nick:string -> unit ->
connection_t Io.t
(** Connect to an IRC server at address [addr]. The PASS command will be
sent if [password] is not None. *)

val connect_by_name :
?username:string -> ?mode:int -> ?realname:string -> ?password:string ->
server:string -> port:int -> nick:string -> unit ->
connection_t option Io.t
(** Try to resolve the [server] name using DNS, otherwise behaves like
{!connect}. Returns [None] if no IP could be found for the given
name. *)

(** Information on keeping the connection alive *)
type keepalive = {
mode: [`Active | `Passive];
timeout: int;
}

val default_keepalive : keepalive
(** Default value for keepalive: active mode with auto-reconnect *)

val listen :
?keepalive:keepalive ->
connection:connection_t ->
callback:(
connection_t ->
Irc_message.parse_result ->
unit Io.t) ->
unit ->
unit Io.t
(** [listen connection callback] listens for incoming messages on
[connection]. All server pings are handled internally; all other
messages are passed, along with [connection], to [callback].
@param keepalive the behavior on disconnection (if the transport
supports {!Irc_transport.IO.pick} and {!Irc_transport.IO.sleep}) *)

val reconnect_loop :
?keepalive:keepalive ->
after:int ->
connect:(unit -> connection_t option Io.t) ->
f:(connection_t -> unit Io.t) ->
callback:(
connection_t ->
Irc_message.parse_result ->
unit Io.t) ->
unit ->
unit Io.t
(** A combination of {!connect} and {!listen} that, every time
the connection is terminated, tries to start a new one
after [after] seconds.
@param after time before trying to reconnect
@param connect how to reconnect
(a closure over {!connect} or {!connect_by_name})
@param callback the callback for {!listen}
@param f the function to call after connection *)

val set_log : (string -> unit Io.t) -> unit
(** Set logging function *)
end

module Make : functor (Io: Irc_transport.IO) ->
CLIENT with type 'a Io.t = 'a Io.t
and type Io.inet_addr = Io.inet_addr
and type Io.config = Io.config
4 changes: 2 additions & 2 deletions lwt/irc_client_lwt.ml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Io = struct
module Io_lwt = struct
type 'a t = 'a Lwt.t
let (>>=) = Lwt.bind
let return = Lwt.return
Expand Down Expand Up @@ -42,4 +42,4 @@ module Io = struct
let pick = Some Lwt.pick
end

include Irc_client.Make(Io)
include Irc_client.Make(Io_lwt)
8 changes: 5 additions & 3 deletions lwt/irc_client_lwt.mli
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
module Io : Irc_transport.IO
module Io_lwt : Irc_transport.IO
with type 'a t = 'a Lwt.t
and type inet_addr = Lwt_unix.inet_addr
and type file_descr = Lwt_unix.file_descr
and type config = unit

include module type of Irc_client.Make(Io)

include Irc_client.CLIENT
with type 'a Io.t = 'a Io_lwt.t
and type Io.inet_addr = Io_lwt.inet_addr
and type Io.config = unit
4 changes: 2 additions & 2 deletions tls/irc_client_tls.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
open Lwt.Infix

module Io = struct
module Io_tls = struct
type 'a t = 'a Lwt.t
let (>>=) = Lwt.bind
let return = Lwt.return
Expand Down Expand Up @@ -45,4 +45,4 @@ module Io = struct
let pick = Some Lwt.pick
end

include Irc_client.Make(Io)
include Irc_client.Make(Io_tls)
4 changes: 2 additions & 2 deletions tls/irc_client_tls.mli
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

module Io : sig
module Io_tls : sig
type 'a t = 'a Lwt.t

type file_descr = {
Expand All @@ -19,4 +19,4 @@ module Io : sig
and type config := config
end

include module type of Irc_client.Make(Io)
include module type of Irc_client.Make(Io_tls)
4 changes: 2 additions & 2 deletions unix/irc_client_unix.ml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Io = struct
module Io_unix = struct
type 'a t = 'a
let (>>=) x f = f x
let return x = x
Expand Down Expand Up @@ -37,4 +37,4 @@ module Io = struct
let pick = None
end

include Irc_client.Make(Io)
include Irc_client.Make(Io_unix)
7 changes: 5 additions & 2 deletions unix/irc_client_unix.mli
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
module Io : Irc_transport.IO
module Io_unix : Irc_transport.IO
with type 'a t = 'a
and type inet_addr = Unix.inet_addr
and type file_descr = Unix.file_descr
and type config = unit

include module type of Irc_client.Make(Io)
include Irc_client.CLIENT
with type 'a Io.t = 'a Io_unix.t
and type Io.inet_addr = Io_unix.inet_addr
and type Io.config = unit

0 comments on commit 364253a

Please sign in to comment.