Skip to content

Instantly share code, notes, and snippets.

@johnhaley81
Created October 13, 2018 01:07
Show Gist options
  • Save johnhaley81/ab4707a42efaa9a13206614a30cd6279 to your computer and use it in GitHub Desktop.
Save johnhaley81/ab4707a42efaa9a13206614a30cd6279 to your computer and use it in GitHub Desktop.
module Decode = {
type failure = [ DecodeBase.failure | `InvalidOption];
let failureToString = (v: failure, json) =>
(
switch (v) {
| `ExpectedBoolean => "Expected boolean"
| `ExpectedString => "Expected string"
| `ExpectedNumber => "Expected number"
| `ExpectedInt => "Expected int"
| `ExpectedArray => "Expected array"
| `ExpectedObject => "Expected object"
/* TODO: This shouldn't be such a generic error */
| `InvalidOption => "Expected a value in range for enum"
}
)
++ " but found "
++ Js.Json.stringify(json);
module ResultUtil =
Decode.ParseError.ResultOf({
type t = failure;
let handle = x => (x :> t);
});
include Belt.Result;
include DecodeBase.DecodeBase(
ResultUtil.TransformError,
ResultUtil.Monad,
ResultUtil.Alt,
);
module ParseError = Decode.ParseError;
include ResultUtil.Infix;
};
module Encode = {
type encoder('a) = 'a => Js.Json.t;
[@bs.val] external null: Js.Json.t = "";
external string: string => Js.Json.t = "%identity";
external float: float => Js.Json.t = "%identity";
external int: int => Js.Json.t = "%identity";
external dict: Js_dict.t(Js.Json.t) => Js.Json.t = "%identity";
external boolean: bool => Js.Json.t = "%identity";
let char = c => c |> String.make(1) |> string;
let date = d => d |> Js.Date.toJSONUnsafe |> string;
let optional = encode =>
fun
| None => null
| Some(v) => encode(v);
let withDefault = (d, encode) =>
fun
| None => d
| Some(v) => encode(v);
let object_ = props: Js.Json.t => props |> Js.Dict.fromList |> dict;
external jsonArray: array(Js.Json.t) => Js.Json.t = "%identity";
let array = (encode, l) => l |> Array.map(encode) |> jsonArray;
let arrayOf = array;
let list = (encode, l) =>
l |> List.map(encode) |> Array.of_list |> jsonArray;
let pair = (encodeA, encodeB, (a, b)) =>
jsonArray([|encodeA(a), encodeB(b)|]);
let tuple2 = pair;
let tuple3 = (encodeA, encodeB, encodeC, (a, b, c)) =>
jsonArray([|encodeA(a), encodeB(b), encodeC(c)|]);
let tuple4 = (encodeA, encodeB, encodeC, encodeD, (a, b, c, d)) =>
jsonArray([|encodeA(a), encodeB(b), encodeC(c), encodeD(d)|]);
external stringArray: array(string) => Js.Json.t = "%identity";
external numberArray: array(float) => Js.Json.t = "%identity";
external boolArray: array(bool) => Js.Json.t = "%identity";
};
type t = {
id: string,
imdb: string,
tmdbId: int,
profileId: string,
status: string,
title: string,
type_: string,
};
let make = (id, imdb, tmdbId, profileId, status, title, type_) => {
id,
imdb,
tmdbId,
profileId,
status,
title,
type_,
};
let decode = json =>
Json.Decode.(
make
<$> field("id", string, json)
<*> field("imdb", string, json)
<*> field("tmdbId", int, json)
<*> field("profile_id", string, json)
<*> field("status", string, json)
<*> field("title", string, json)
<*> field("type", string, json)
);
let encode = ({id, imdb, tmdbId, profileId, status, title, type_}) =>
Json.Encode.(
object_([
("id", id |> string),
("imdb", imdb |> string),
("tmdbId", tmdbId |> int),
("profile_id", profileId |> string),
("status", status |> string),
("title", title |> string),
("type", type_ |> string),
])
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment