sig
  module Implementation :
    sig
      type 'connection_state t = 'connection_state Rpc.Implementation.t
      module Description :
        sig
          type t =
            Rpc.Implementation.Description.t = {
            name : string;
            version : int;
          }
          val t_of_sexp : Sexplib.Sexp.t -> t
          val sexp_of_t : t -> Sexplib.Sexp.t
        end
      val description : 'a t -> Description.t
      val lift : 'a t -> f:('-> 'a) -> 'b t
    end
  module Implementations :
    sig
      type 'connection_state t = 'connection_state Rpc.Implementations.t
      val null : unit -> 'connection_state t
      val create :
        implementations:'connection_state Implementation.t list ->
        on_unknown_rpc:[ `Call of rpc_tag:string -> version:int -> unit
                       | `Ignore
                       | `Raise ] ->
        ('connection_state t,
         [ `Duplicate_implementations of Implementation.Description.t list ])
        Core.Std.Result.t
      val create_exn :
        implementations:'connection_state Implementation.t list ->
        on_unknown_rpc:[ `Call of rpc_tag:string -> version:int -> unit
                       | `Ignore
                       | `Raise ] ->
        'connection_state t
    end
  module type Connection =
    sig
      type t
      val create :
        ?implementations:'Implementations.t ->
        connection_state:'->
        ?max_message_size:int ->
        Import.Reader.t ->
        Import.Writer.t ->
        (t, Core.Std.Exn.t) Core.Std.Result.t Import.Deferred.t
      val close : t -> unit Import.Deferred.t
      val close_finished : t -> unit Import.Deferred.t
      val is_closed : t -> bool
      val bytes_to_write : t -> int
      val with_close :
        ?implementations:'Implementations.t ->
        connection_state:'->
        Import.Reader.t ->
        Import.Writer.t ->
        dispatch_queries:(t -> 'Import.Deferred.t) ->
        on_handshake_error:[ `Call of Core.Std.Exn.t -> 'Import.Deferred.t
                           | `Raise ] ->
        'Import.Deferred.t
      val server_with_close :
        Import.Reader.t ->
        Import.Writer.t ->
        implementations:'Implementations.t ->
        connection_state:'->
        on_handshake_error:[ `Call of
                               Core.Std.Exn.t -> unit Import.Deferred.t
                           | `Ignore
                           | `Raise ] ->
        unit Import.Deferred.t
      val serve :
        implementations:'Implementations.t ->
        initial_connection_state:(([< Import.Socket.Address.t ] as 'a) -> 's) ->
        where_to_listen:('a, 'listening_on) Tcp.Where_to_listen.t ->
        ?auth:('-> bool) ->
        ?on_handshake_error:[ `Call of Core.Std.Exn.t -> unit
                            | `Ignore
                            | `Raise ] ->
        unit -> ('a, 'listening_on) Tcp.Server.t Import.Deferred.t
      module Client_implementations :
        sig
          type 's t = {
            connection_state : 's;
            implementations : 'Implementations.t;
          }
          val null : unit -> unit t
        end
      val client :
        host:string ->
        port:int ->
        ?implementations:'Client_implementations.t ->
        unit -> (t, Core.Std.Exn.t) Core.Std.Result.t Import.Deferred.t
      val with_client :
        host:string ->
        port:int ->
        ?implementations:'Client_implementations.t ->
        (t -> 'Import.Deferred.t) ->
        ('a, Core.Std.Exn.t) Core.Std.Result.t Import.Deferred.t
    end
  module Connection :
    sig
      type t = Rpc.Connection.t
      val create :
        ?implementations:'Implementations.t ->
        connection_state:'->
        ?max_message_size:int ->
        Import.Reader.t ->
        Import.Writer.t ->
        (t, Core.Std.Exn.t) Core.Std.Result.t Import.Deferred.t
      val close : t -> unit Import.Deferred.t
      val close_finished : t -> unit Import.Deferred.t
      val is_closed : t -> bool
      val bytes_to_write : t -> int
      val with_close :
        ?implementations:'Implementations.t ->
        connection_state:'->
        Import.Reader.t ->
        Import.Writer.t ->
        dispatch_queries:(t -> 'Import.Deferred.t) ->
        on_handshake_error:[ `Call of Core.Std.Exn.t -> 'Import.Deferred.t
                           | `Raise ] ->
        'Import.Deferred.t
      val server_with_close :
        Import.Reader.t ->
        Import.Writer.t ->
        implementations:'Implementations.t ->
        connection_state:'->
        on_handshake_error:[ `Call of
                               Core.Std.Exn.t -> unit Import.Deferred.t
                           | `Ignore
                           | `Raise ] ->
        unit Import.Deferred.t
      val serve :
        implementations:'Implementations.t ->
        initial_connection_state:(([< Import.Socket.Address.t ] as 'a) -> 's) ->
        where_to_listen:('a, 'listening_on) Tcp.Where_to_listen.t ->
        ?auth:('-> bool) ->
        ?on_handshake_error:[ `Call of Core.Std.Exn.t -> unit
                            | `Ignore
                            | `Raise ] ->
        unit -> ('a, 'listening_on) Tcp.Server.t Import.Deferred.t
      module Client_implementations :
        sig
          type 's t =
            'Rpc.Connection.Client_implementations.t = {
            connection_state : 's;
            implementations : 'Implementations.t;
          }
          val null : unit -> unit t
        end
      val client :
        host:string ->
        port:int ->
        ?implementations:'Client_implementations.t ->
        unit -> (t, Core.Std.Exn.t) Core.Std.Result.t Import.Deferred.t
      val with_client :
        host:string ->
        port:int ->
        ?implementations:'Client_implementations.t ->
        (t -> 'Import.Deferred.t) ->
        ('a, Core.Std.Exn.t) Core.Std.Result.t Import.Deferred.t
    end
  module Rpc :
    sig
      type ('query, 'response) t = ('query, 'response) Rpc.Rpc.t
      val create :
        name:string ->
        version:int ->
        bin_query:'query Core.Std.Bin_prot.Type_class.t ->
        bin_response:'response Core.Std.Bin_prot.Type_class.t ->
        ('query, 'response) t
      val name : ('a, 'b) t -> string
      val version : ('a, 'b) t -> int
      val implement :
        ('query, 'response) t ->
        ('connection_state -> 'query -> 'response Import.Deferred.t) ->
        'connection_state Implementation.t
      val dispatch :
        ('query, 'response) t ->
        Connection.t ->
        'query -> 'response Core.Std.Or_error.t Import.Deferred.t
      val dispatch_exn :
        ('query, 'response) t ->
        Connection.t -> 'query -> 'response Import.Deferred.t
    end
  module Pipe_rpc :
    sig
      type ('query, 'response, 'error) t =
          ('query, 'response, 'error) Rpc.Pipe_rpc.t
      module Id : sig type t = Rpc.Pipe_rpc.Id.t end
      val create :
        name:string ->
        version:int ->
        bin_query:'query Core.Std.Bin_prot.Type_class.t ->
        bin_response:'response Core.Std.Bin_prot.Type_class.t ->
        bin_error:'error Core.Std.Bin_prot.Type_class.t ->
        ('query, 'response, 'error) t
      val implement :
        ('query, 'response, 'error) t ->
        ('connection_state ->
         'query ->
         aborted:unit Import.Deferred.t ->
         ('response Import.Pipe.Reader.t, 'error) Core.Std.Result.t
         Import.Deferred.t) ->
        'connection_state Implementation.t
      val dispatch :
        ('query, 'response, 'error) t ->
        Connection.t ->
        'query ->
        ('response Import.Pipe.Reader.t * Id.t, 'error) Core.Std.Result.t
        Core.Std.Or_error.t Import.Deferred.t
      val dispatch_exn :
        ('query, 'response, 'error) t ->
        Connection.t ->
        'query -> ('response Import.Pipe.Reader.t * Id.t) Import.Deferred.t
      val abort : ('a, 'b, 'c) t -> Connection.t -> Id.t -> unit
      val name : ('a, 'b, 'c) t -> string
      val version : ('a, 'b, 'c) t -> int
    end
  module State_rpc :
    sig
      type ('query, 'state, 'update, 'error) t =
          ('query, 'state, 'update, 'error) Rpc.State_rpc.t
      module Id : sig type t = Rpc.State_rpc.Id.t end
      val create :
        name:string ->
        version:int ->
        bin_query:'query Core.Std.Bin_prot.Type_class.t ->
        bin_state:'state Core.Std.Bin_prot.Type_class.t ->
        bin_update:'update Core.Std.Bin_prot.Type_class.t ->
        bin_error:'error Core.Std.Bin_prot.Type_class.t ->
        ('query, 'state, 'update, 'error) t
      val implement :
        ('query, 'state, 'update, 'error) t ->
        ('connection_state ->
         'query ->
         aborted:unit Import.Deferred.t ->
         ('state * 'update Import.Pipe.Reader.t, 'error) Core.Std.Result.t
         Import.Deferred.t) ->
        'connection_state Implementation.t
      val dispatch :
        ('query, 'state, 'update, 'error) t ->
        Connection.t ->
        'query ->
        update:('state -> 'update -> 'state) ->
        ('state * ('state * 'update) Import.Pipe.Reader.t * Id.t, 'error)
        Core.Std.Result.t Core.Std.Or_error.t Import.Deferred.t
      val abort : ('a, 'b, 'c, 'd) t -> Connection.t -> Id.t -> unit
      val name : ('a, 'b, 'c, 'd) t -> string
      val version : ('a, 'b, 'c, 'd) t -> int
    end
end