Skip to content

Commit

Permalink
Merge pull request #73 from mattjbray/simon/add-otoml
Browse files Browse the repository at this point in the history
add basic otoml support
  • Loading branch information
c-cube authored Apr 29, 2024
2 parents d15a4a9 + 5956cea commit aa4386f
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ jobs:
with:
ocaml-compiler: ${{ matrix.ocaml-compiler }}
opam-depext-flags: --with-test
allow-prerelease-opam: true
dune-cache: true
opam-local-packages: |
decoders.opam
${{ matrix.package }}.opam
Expand Down
32 changes: 32 additions & 0 deletions decoders-otoml.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: "Otoml backend for decoders"
maintainer: ["Matt Bray <[email protected]>"]
authors: ["Matt Bray <[email protected]>"]
license: "ISC"
homepage: "https://github.com/mattjbray/ocaml-decoders"
doc: "https://mattjbray.github.io/ocaml-decoders/"
bug-reports: "https://github.com/mattjbray/ocaml-decoders/issues"
depends: [
"dune" {>= "3.1"}
"ocaml" {>= "4.03.0"}
"decoders" {= version}
"otoml" {>= "1.0"}
"containers" {with-test & >= "0.16"}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/mattjbray/ocaml-decoders.git"
10 changes: 10 additions & 0 deletions dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@
(containers (and :with-test (>= 0.16)))
(odoc :with-doc)))

(package
(name decoders-otoml)
(synopsis "Otoml backend for decoders")
(depends
(ocaml (>= 4.03.0))
(decoders (= :version))
(otoml (>= 1.0))
(containers (and :with-test (>= 0.16)))
(odoc :with-doc)))

(package
(name decoders-yojson)
(synopsis "Yojson backend for decoders")
Expand Down
86 changes: 86 additions & 0 deletions src-otoml/decoders_otoml.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
(** {2 Yojson implementation} *)

open Decoders

module Make
(Toml : Otoml.Base.TomlImplementation
with type toml_integer = int
and type toml_float = float) =
struct
module T = Toml

module Toml_decodeable : Decode.Decodeable with type value = T.t = struct
type value = Toml.t

let pp fmt v = Format.fprintf fmt "@[%s@]" (T.Printer.to_string v)

let of_string : string -> (value, string) result =
fun string -> T.Parser.from_string_result string


let of_file file = T.Parser.from_file_result file

let get_string = function T.TomlString value -> Some value | _ -> None

let get_int = function T.TomlInteger value -> Some value | _ -> None

let get_float = function
| T.TomlFloat value ->
Some value
| T.TomlInteger value ->
Some (float_of_int value)
| _ ->
None


let get_bool = function T.TomlBoolean value -> Some value | _ -> None

let get_null = function T.TomlString "" -> Some () | _ -> None

let get_list : value -> value list option = function
| T.TomlArray l | T.TomlTableArray l ->
Some l
| _ ->
None


let get_key_value_pairs : value -> (value * value) list option = function
| T.TomlTable assoc | T.TomlInlineTable assoc ->
Some (List.map (fun (key, value) -> (T.string key, value)) assoc)
| _ ->
None


let to_list values = T.array values
end

module Decode = Decode.Make (Toml_decodeable)

module Toml_encodeable = struct
type value = Toml.t

let to_string v = Toml.Printer.to_string v

let of_string = Toml.string

let of_int = Toml.integer

let of_float = Toml.float

let of_bool = Toml.boolean

let null = Toml.string ""

let of_list = Toml.array

let of_key_value_pairs xs =
Toml.inline_table
( xs
|> Util.My_list.filter_map (fun (k, v) ->
match k with Toml.TomlString k -> Some (k, v) | _ -> None ) )
end

module Encode = Encode.Make (Toml_encodeable)
end

include Make (Otoml)
14 changes: 14 additions & 0 deletions src-otoml/decoders_otoml.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(** Turn JSON values into Ocaml values. *)

module Make
(Toml : Otoml.Base.TomlImplementation
with type toml_integer = int
and type toml_float = float) : sig
module Decode : Decoders.Decode.S with type value = Toml.t

module Encode : Decoders.Encode.S with type value = Toml.t
end

module Decode : Decoders.Decode.S with type value = Otoml.t

module Encode : Decoders.Encode.S with type value = Otoml.t
6 changes: 6 additions & 0 deletions src-otoml/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

(library
(name decoders_otoml)
(public_name decoders-otoml)
(flags :standard -warn-error -a+8)
(libraries decoders otoml))
4 changes: 4 additions & 0 deletions test-otoml/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(test
(name main)
(package decoders-otoml)
(libraries decoders-otoml containers ounit2))
35 changes: 35 additions & 0 deletions test-otoml/main.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
open OUnit2

let otoml_suite =
let open Decoders_otoml.Decode in
let decoder_test ~decoder ~input ~expected _test_ctxt =
match decode_string decoder input with
| Ok value ->
assert_equal value expected
| Error error ->
assert_string (Format.asprintf "%a" pp_error error)
in

"otoml"
>::: [ "basic"
>:: decoder_test
~decoder:
(let+ a = field "a" int
and+ b = field "b" float in
(a, b) )
~input:"a=1\nb=42.5"
~expected:(1, 42.5)
; "table"
>:: decoder_test
~decoder:(field "sub" (field_opt "a" int))
~input:"[sub]\na = 42"
~expected:(Some 42)
; "table (field absent)"
>:: decoder_test
~decoder:(field "sub" (field_opt "a" int))
~input:"[sub]\nb = false"
~expected:None
]


let () = "decoders" >::: [ otoml_suite ] |> run_test_tt_main

0 comments on commit aa4386f

Please sign in to comment.