mte/unikernel/duniverse/mimic/lib/mimic.mli

136 lines
4.3 KiB
OCaml
Raw Normal View History

2025-11-11 02:07:51 +01:00
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