Skip to content

Instantly share code, notes, and snippets.

@hulufei
Created August 22, 2018 03:26
Show Gist options
  • Save hulufei/309cbf4830f23e2e4fdd6540d5b08a72 to your computer and use it in GitHub Desktop.
Save hulufei/309cbf4830f23e2e4fdd6540d5b08a72 to your computer and use it in GitHub Desktop.
type tree =
| Leaf(string)
| Node(Js.Dict.t(tree));
type dictTree = Js.Dict.t(tree);
type translations =
| Translations(Js.Dict.t(string));
let rec treeDecoder = json =>
json
|> Json.Decode.(
oneOf([
string |> map(s => s |. Leaf),
dict(treeDecoder) |> map(t => t |. Node),
])
);
/* Apply only to single key-dtree entry, construct namespace for each entry */
let rec array_entries_of_dict_tree = (parentKey, dtree) =>
dtree
|> Js.Dict.entries
|> Array.fold_left(
(arr, (k, v)) => {
let newKey = parentKey ++ "." ++ k;
(
switch (v) {
| Leaf(str) => [|(newKey, str)|]
| Node(dt) => dt |> array_entries_of_dict_tree(newKey)
}
)
|> Array.append(arr);
},
[||],
);
let dict_string_of_dict_tree = dtree =>
dtree
|> Js.Dict.entries
|> Array.map(((k, v)) =>
switch (v) {
| Leaf(str) => [|(k, str)|]
| Node(dt) => dt |> array_entries_of_dict_tree(k)
}
)
|> Array.to_list
|> Array.concat
|> Js.Dict.fromArray;
let translationsDecoder =
Json.Decode.(
dict(treeDecoder)
|> map(dt => dt |> dict_string_of_dict_tree |. Translations)
);
let t = (Translations(translations), key, fallback) =>
translations |. Js.Dict.get(key) |. Belt.Option.getWithDefault(fallback);
let tr = (translations, key, fallback) =>
t(translations, key, fallback) |> ReasonReact.string;
[%raw {| require("./locales/zh-CN.json") |}] |> translationsDecoder
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment