Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: use mdx to check examples #6

Merged
merged 10 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/actions/libextism/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ runs:
- name: Install
shell: bash
run: sudo extism lib install --version git
env:
GITHUB_TOKEN: ${{ github.token }}
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
if: steps.cache-ocaml.outputs.cache-hit != 'true'
run: |
opam upgrade -y
opam install -y --deps-only .
opam install -y --deps-only --with-test --with-doc .
LD_LIBRARY_PATH=/usr/local/lib opam exec -- dune build
- name: Test OCaml Host SDK
run: |
Expand Down
4 changes: 4 additions & 0 deletions .ocamlformat
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
version = 0.26.1
doc-comments = after-when-possible
doc-comments-padding = 2
doc-comments-tag-only = default
parse-docstrings = true
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,24 @@ let hello_world =
@@ fun plugin user_data ->

(* Get the input *)
let s = Host_function.param plugin Type.string in
print_endline ("Original input: " ^ s);
let s = Host_function.input plugin Type.string in
print_endline ("Original input: " ^ Error.unwrap s);

(* Print the userdata *)
let () = print_endline user_data in

(* Return a JSON value *)
Host_function.result plugin Type.json (`Assoc [ ("count", `Int 999) ])
Host_function.output plugin Type.json (`Assoc [ ("count", `Int 999) ])

let () =
(* Create a manifest using a file from disk *)
let manifest = Manifest.(create [ Wasm.file "test/code-functions.wasm" ]) in
let manifest = Manifest.(create [ Wasm.file "wasm/code-functions.wasm" ]) in

(* Create a plugin from the manifest with the [hello_world] host function *)
let plugin = Plugin.of_manifest manifest ~functions:[hello_world] ~wasi:true |> Error.unwrap in

(* Call [count_vowels] *)
let output = Plugin.call_string plugin ~name:"count_vowels" "this is a test" in
let output = Plugin.call_string plugin ~name:"count_vowels" "this is a test" |> Error.unwrap in

(* Print the result *)
print_endline output
Expand Down
5 changes: 5 additions & 0 deletions dune
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
(dirs :standard \ runtime)

(mdx
(package extism)
(libraries extism-manifest extism yojson)
(deps wasm/code-functions.wasm))
3 changes: 3 additions & 0 deletions dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

(name extism)

(using mdx 0.3)

(generate_opam_files true)

(source
Expand Down Expand Up @@ -30,6 +32,7 @@
(ppx_inline_test (>= v0.15.0))
(cmdliner (>= 1.1.1))
(uuidm (>= 0.9.0))
(mdx (and :dev :with-test))
)
(tags
(topics wasm plugin)))
Expand Down
4 changes: 4 additions & 0 deletions extism.opam
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ depends: [
"ppx_inline_test" {>= "v0.15.0"}
"cmdliner" {>= "1.1.1"}
"uuidm" {>= "0.9.0"}
"mdx" {dev & with-test}
"odoc" {with-doc}
]
build: [
Expand All @@ -39,3 +40,6 @@ build: [
dev-repo: "git+https://github.com/extism/ocaml-sdk.git"
build-env: [EXTISM_TEST_NO_LIB = ""]
post-messages: ["See https://extism.org/docs/install/ for information about installing libextism"]
pin-depends: [
[ "mdx.dev" "git+https://github.com/realworldocaml/mdx#9586620d81c923b98819042f67a8ce664b2552ac" ]
]
3 changes: 3 additions & 0 deletions extism.opam.template
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
build-env: [EXTISM_TEST_NO_LIB = ""]
post-messages: ["See https://extism.org/docs/install/ for information about installing libextism"]
pin-depends: [
[ "mdx.dev" "git+https://github.com/realworldocaml/mdx#9586620d81c923b98819042f67a8ce664b2552ac" ]
]
76 changes: 45 additions & 31 deletions lib/extism.mli
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
(** Extism bindings for OCaml *)
(** Extism bindings for OCaml

{1 Introduction}

Extism is a framework for executing WebAssembly plugins. The OCaml bindings require libextism,
installation information is available on {{: https://extism.org/docs/install }the Extism website}

{1 API 1}
*)

val extism_version : unit -> string
(** Returns the libextism version, not the version of the OCaml library *)
Expand All @@ -14,10 +22,10 @@ module Error : sig
(** Exception type *)

val unwrap : ('a, t) result -> 'a
(** Like {!Result.get_ok} for {!t} *)
(** Like [Result.get_ok] for {!t} *)

val throw : t -> 'a
(** Raise [t] as an exception *)
(** Raise {!t} as an exception *)
end

(** [Val] represents low-level WebAssembly values *)
Expand Down Expand Up @@ -110,9 +118,9 @@ module Type : sig
(** Encode a value to a string *)

val decode : Bigstringaf.t -> (t, Error.t) result
(** Decode a value from a bigstring. The bigstring argument uses a direct pointer
into the plugin memory, this means it shouldn't be stored outside of this function
without being copied first *)
(** Decode a value from a bigstring. The bigstring argument uses a direct
pointer into the plugin memory, this means it shouldn't be stored
outside of this function without being copied first *)
end

module String : S with type t = string
Expand All @@ -128,16 +136,20 @@ module Type : sig
(** Json type *)

val string : (module S with type t = string)
(** String type helper, this can be passed to a function expecting a wrapped module *)
(** String type helper, this can be passed to a function expecting a wrapped
module *)

val bytes : (module S with type t = bytes)
(** Bytes type helper, this can be passed to a function expecting a wrapped module *)
(** Bytes type helper, this can be passed to a function expecting a wrapped
module *)

val bigstring : (module S with type t = Bigstringaf.t)
(** Bigstring type helper, this can be passed to a function expecting a wrapped module *)
(** Bigstring type helper, this can be passed to a function expecting a
wrapped module *)

val json : (module S with type t = Yojson.Safe.t)
(** Json type helper, this can be passed to a function expecting a wrapped module *)
(** Json type helper, this can be passed to a function expecting a wrapped
module *)
end

(** [Host_function] represents the plugin that is currently running, it should
Expand All @@ -156,16 +168,18 @@ module Host_function : sig
(** Represents a block of guest memory *)

val output_string : t -> ?index:int -> string -> unit
(** Return a string from a host function, this copies the string into memory and
sets the results array at [index] with the pointer to the allocated value *)
(** Return a string from a host function, this copies the string into memory
and sets the results array at [index] with the pointer to the allocated
value *)

val output_bigstring : t -> ?index:int -> Bigstringaf.t -> unit
(** Return a bigstring from a host function, this copies the bigstring into memory and
sets the results array at [index] with the pointer to the allocated value *)
(** Return a bigstring from a host function, this copies the bigstring into
memory and sets the results array at [index] with the pointer to the
allocated value *)

val input_string : ?index:int -> t -> string
(** Get a string argument, the parameter at [index] should be an int64 value that points to the
string in linear memory *)
(** Get a string argument, the parameter at [index] should be an int64 value
that points to the string in linear memory *)

val input_bigstring : ?index:int -> t -> Bigstringaf.t
(** Load a parameter directly from memory *)
Expand Down Expand Up @@ -198,8 +212,8 @@ module Host_function : sig
(** Convert [Val] to memory block *)

val of_val_exn : t -> Val.t -> memory_handle
(** Convert [Val] to memory block, raises [Invalid_argument] if the value is not a pointer
to a valid memory block *)
(** Convert [Val] to memory block, raises [Invalid_argument] if the value is
not a pointer to a valid memory block *)

val get_string : t -> memory_handle -> string
(** Get a string from memory stored at the provided offset *)
Expand All @@ -215,8 +229,8 @@ module Host_function : sig
end
end

(** [Function] is used to create new a new function, which can be called
from a WebAssembly plugin *)
(** [Function] is used to create new a new function, which can be called from a
WebAssembly plugin *)
module Function : sig
type t
(** Function type *)
Expand All @@ -229,12 +243,11 @@ module Function : sig
user_data:'a ->
(Host_function.t -> 'a -> unit) ->
t
(** Create a new function, [Function.v name ~params ~results ~user_data f] creates
a new [Function] with the given [name], [params] specifies the argument types,
[results] specifies the return types, [user_data] is used to pass arbitrary
OCaml values into the function and [f] is the OCaml function that will be
called.
*)
(** Create a new function, [Function.v name ~params ~results ~user_data f]
creates a new [Function] with the given [name], [params] specifies the
argument types, [results] specifies the return types, [user_data] is used
to pass arbitrary OCaml values into the function and [f] is the OCaml
function that will be called. *)

val with_namespace : t -> string -> t
(** Update a function's namespace *)
Expand Down Expand Up @@ -277,11 +290,12 @@ module Plugin : sig
name:string ->
'a ->
('b, Error.t) result
(** [call t ~name input_type output_type input] executes a function with typed input and output *)
(** [call t ~name input_type output_type input] executes a function with typed
input and output *)

val free : t -> unit
(** Free a plugin immediately, this isn't normally required unless there are a lot of plugins ope
at once *)
(** Free a plugin immediately, this isn't normally required unless there are a
lot of plugins open at once *)

val function_exists : t -> string -> bool
(** Check if a function is exported by a plugin *)
Expand All @@ -301,5 +315,5 @@ module Plugin : sig
end

val with_plugin : (Plugin.t -> 'a) -> Plugin.t -> 'a
(** Create a Plugin that can be used within the scope of the provided callback, it will
automatically be freed when the function returns *)
(** Create a Plugin that can be used within the scope of the provided callback,
it will automatically be freed when the function returns *)
2 changes: 1 addition & 1 deletion manifest/extism_manifest.ml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ module Wasm = struct
type url = {
url : string;
headers : dict option; [@yojson.option]
name : string option; [@yojson.option]
meth : string option; [@yojson.option] [@key "method"]
name : string option; [@yojson.option]
hash : string option; [@yojson.option]
}
[@@deriving yojson]
Expand Down
35 changes: 21 additions & 14 deletions manifest/extism_manifest.mli
Original file line number Diff line number Diff line change
@@ -1,41 +1,48 @@
type memory_options = { max_pages : int option } [@@deriving yojson]
(** Extism manifest

This package provides an OCaml interface for the {{: https://extism.org/docs/concepts/manifest} Extism manifest}
*)

type memory_options = {
max_pages : int option (** [max_pages] can be used to limit the total number of pages used by the runtime *)
} [@@deriving yojson]
(** Memory options *)

type dict = (string * string) list [@@deriving yojson]
(** Key/value dictionary *)

type config = (string * string option) list [@@deriving yojson]
(** Key/value dictionary with optional values *)
(** Key/value dictionary with optional values, used for passing values into a plugin at runtime *)

module Wasm : sig
type file = {
path : string;
name : string option; [@yojson.option]
hash : string option; [@yojson.option]
path : string; (** Path to Wasm module on disk *)
name : string option; [@yojson.option] (** Optional name of module for linking *)
hash : string option; [@yojson.option] (** Optional hash for verification *)
}
[@@deriving yojson]
(** WebAssembly file *)

type data = {
data : string;
name : string option; [@yojson.option]
hash : string option; [@yojson.option]
data : string; (** A string containing a Wasm module *)
name : string option; [@yojson.option] (** Optional name of module for linking *)
hash : string option; [@yojson.option] (** Optional hash for verification *)
}
[@@deriving yojson]
(** WebAssembly module data *)

type url = {
url : string;
headers : dict option; [@yojson.option]
name : string option; [@yojson.option]
meth : string option; [@yojson.option] [@key "method"]
hash : string option; [@yojson.option]
url : string; (** A URL to a Wasm module *)
headers : dict option; [@yojson.option] (** Request headers *)
meth : string option; [@yojson.option] [@key "method"] (** Request method *)
name : string option; [@yojson.option] (** Optional name of module for linking *)
hash : string option; [@yojson.option] (** Optional hash for verification *)
}
[@@deriving yojson]
(** WebAssembly URL *)

(** WebAssembly from a file, module data or URL *)
type t = File of file | Data of data | Url of url [@@deriving yojson]
(** WebAssembly from a file, module data or URL *)

val file : ?name:string -> ?hash:string -> string -> t
(** Create [wasm] from filename *)
Expand Down