module Mirage_protocol = Mirage_protocol type flow = private .. (** The type for flows. A flow represents the state of a single reliable stream stream that is connected to an {i endpoint}. *) include Mirage_flow.S with type flow := flow and type error = [ `Msg of string | `Not_found | `Cycle ] type ctx (** The type for contexts. It's a {i heterogeneous map} of values to help mimic to instantiate a new {!type:flow} {i via} {!val:resolve}. *) type 'edn value (** The type for {i witnesses} whose lookup value is of type ['edn]. *) module Fun : sig type ('k, 'res) args = | [] : ('res, 'res) args | ( :: ) : 'a arg * ('k, 'res) args -> ('a -> 'k, 'res) args and 'v arg val req : 'a value -> 'a arg val opt : 'a value -> 'a option arg val dft : 'a value -> 'a -> 'a arg val map : ('k, 'a) args -> 'k -> 'a arg end val make : name:string -> 'edn value (** [make ~name] is a new witness. *) val add : 'edn value -> 'edn -> ctx -> ctx (** [add w v ctx] is [ctx] with [w] bound to [v]. *) val get : 'edn value -> ctx -> 'edn option (** [get w ctx] is the value of [w]'s binding in [ctx], if any. *) val replace : 'edn value -> 'edn -> ctx -> ctx (** [replace w v ctx] replaces the value of [w] by [v] if it exists or bound [w] to [v]. *) val fold : 'edn value -> ('k, 'edn option Lwt.t) Fun.args -> k:'k -> ctx -> ctx val merge : ctx -> ctx -> ctx val empty : ctx (** [empty] is the empty context. *) type ('edn, 'flow) protocol val register : ?priority:int -> name:string -> (module Mirage_protocol.S with type flow = 'flow and type endpoint = 'edn) -> 'edn value * ('edn, 'flow) protocol (** [register ?priority ~name (module Protocol)] registers the given [Protocol] into the internal global Mimic's state as a possible transmission protocol available {i via} {!val:resolve}. [?priority] is used to help mimic to choose between multiple solutions according to the given context. Mimic will choose the lower-priority solution. [name] helps the end-user to know which solution mimic will dynamically {i via} log outputs. [register] returns 2 values: - a {i witness} as the required value to initiate a transmission {i via} the given [Protocol] implementation - a {!type:protocol} which can help the end-user to destruct a {!type:flow} to its structural type {i via} {!val:repr}. *) module type REPR = sig type t type flow += (* XXX(dinosaure): private? *) T of t end val repr : ('edn, 'flow) protocol -> (module REPR with type t = 'flow) (** [repr protocol] gives a module definition with an OCaml constructor to help the end-user to destruct the structural type of a given {!type:flow}: {[ module Protocol : Mirage_protocol.S with type flow = Lwt_unix.file_descr let edn, protocol = Mimic.register ~name:"protocol" (module Protocol) module R = (val (Mimic.repr protocol)) let () = Mimic.resolve ~ctx >>= function | Ok (R.T lwt_unix_file_descr) -> ... | ... ]} *) val resolve : ctx -> (flow, [> error ]) result Lwt.t (** [resolve ctx] tries to instantiate a {!type:flow} from the given [ctx]. *) type edn = | Edn : 'edn value * 'edn -> edn (** The type of a value and its witness. *) type (_, _) refl = Refl : ('a, 'a) refl val equal : 'a value -> 'b value -> ('a, 'b) refl option (** [equal a b] returns a proof that [a] and [b] are {i structurally} equal. *) val unfold : ctx -> (edn list, [> `Cycle ]) result Lwt.t (** [unfold ctx] applies any functions available into the given [ctx] and and possible to compute according to available values and return a list of what these functions return. It's useful to do an introspection of what [mimic] does when it {!val:resolve}s the given [ctx]. From that and {!val:equal}, the user is able to introspect what [mimic] generated and which protocol it is able to instantiate then. {val:resolve} is: {[ let resolve ctx = unfold ctx >>= function | Ok lst -> connect lst | Error _ as err -> Lwt.return err ]} *) val connect : edn list -> (flow, [> error ]) result Lwt.t (** [connect values] tries to instantiate a {!type:flow} from given [values] and registered protocols (see {!val:register}). *) module Merge (A : sig val ctx : ctx end) (B : sig val ctx : ctx end) : sig val ctx : ctx end