Skip to content

Instantly share code, notes, and snippets.

@gmmorris
Created May 16, 2018 19:56
Show Gist options
  • Save gmmorris/2b132aaeafe2265dd8a2b95bafa0f3b4 to your computer and use it in GitHub Desktop.
Save gmmorris/2b132aaeafe2265dd8a2b95bafa0f3b4 to your computer and use it in GitHub Desktop.
Bucklescript bindings approaches for complex Object based arguments
var CryptographyJs = require("./cryptography.js");
CryptographyJs.hash({ algorithm: 'md5', length: 10 }, "asd");
CryptographyJs.hash({ algorithm: 'md5' }, "asd");
CryptographyJs.hash({ length: 10 }, "asd");
CryptographyJs.hash({}, "asd");
Cryptography.hashWithOpts(hashOptions(~algorithm=`MD5, ~length=10, ()), "asd");
Cryptography.hashWithOpts(hashOptions(~algorithm=`MD5, ()), "asd");
Cryptography.hashWithOpts(hashOptions(~length=10, ()), "asd");
Cryptography.hashWithOpts(hashOptions(), "111");
[@bs.deriving jsConverter]
type hash = [
| [@bs.as "sha256"] `SHA256
| [@bs.as "sha512"] `SHA512
| [@bs.as "sha384"] `SHA384
| [@bs.as "sha1"] `SHA1
| [@bs.as "md5"] `MD5
];
[@bs.deriving abstract]
type hashConfig = {
[@bs.optional]
algorithm: string,
[@bs.optional]
length: int,
};
module Crypt_ = {
[@bs.obj]
external hashOptions :
(~algorithm: Js.Nullable.t(string), ~length: Js.Nullable.t(int), unit) =>
hashConfig =
"";
};
let mapNullable = (opt: option('a), cb: 'a => 'b) =>
switch (opt) {
| Some(a) => Js.Nullable.return(cb(a))
| None => Js.Nullable.undefined
};
let hashOptions = (~algorithm=?, ~length=?, ()) =>
Crypt_.hashOptions(
~algorithm=mapNullable(algorithm, hashToJs),
~length=mapNullable(length, i => i),
(),
);
[@bs.module "./cryptography.js"]
external hashWithOpts : (hashConfig, string) => unit = "hash";
hashWithOpts(hashOptions(~algorithm=`MD5, ~length=10, ()), "asd");
hashWithOpts(hashOptions(~algorithm=`MD5, ()), "asd");
hashWithOpts(hashOptions(~length=10, ()), "asd");
hashWithOpts(hashOptions(), "asd");
{ algorithm: 'md5', length: 10 } 'asd'
{ algorithm: 'md5', length: undefined } 'asd'
{ algorithm: undefined, length: 10 } 'asd'
{ algorithm: undefined, length: undefined } 'asd'
[@bs.deriving jsConverter]
type hash = [
| [@bs.as "sha256"] `SHA256
| [@bs.as "sha512"] `SHA512
| [@bs.as "sha384"] `SHA384
| [@bs.as "sha1"] `SHA1
| [@bs.as "md5"] `MD5
];
[@bs.deriving abstract]
type hashConfig = {
[@bs.optional]
algorithm: string,
[@bs.optional]
length: int,
};
module Crypt_ = {
[@bs.obj]
external hashOptions :
(~algorithm: string=?, ~length: int=?, unit) => hashConfig =
"";
};
let mapNullable = (opt: option('a), cb: 'a => 'b) =>
switch (opt) {
| Some(a) => Js.Nullable.return(cb(a))
| None => Js.Nullable.undefined
};
let hashOptions = (~algorithm=?, ~length=?, ()) =>
switch (algorithm) {
| Some(algorithm_) =>
switch (length) {
| Some(length_) =>
Crypt_.hashOptions(
~algorithm=hashToJs(algorithm_),
~length=length_,
(),
)
| None => Crypt_.hashOptions(~algorithm=hashToJs(algorithm_), ())
}
| None =>
switch (length) {
| Some(length_) => Crypt_.hashOptions(~length=length_, ())
| None => Crypt_.hashOptions()
}
};
[@bs.module "./cryptography.js"]
external hashWithOpts : (hashConfig, string) => unit = "hash";
hashWithOpts(hashOptions(~algorithm=`MD5, ~length=10, ()), "asd");
hashWithOpts(hashOptions(~algorithm=`MD5, ()), "asd");
hashWithOpts(hashOptions(~length=10, ()), "asd");
hashWithOpts(hashOptions(), "asd");
{ algorithm: 'md5', length: 10 } 'asd'
{ algorithm: 'md5' } 'asd'
{ length: 10 } 'asd'
{} 'asd'
@gmmorris
Copy link
Author

A...nd got there. Honestly don't get how that wasn't obvious to me. facepalm

type hashConfig;

[@bs.obj]
external hashOptions :
  (~_Algorithm: string=?, ~length: int=?, unit) => hashConfig =
  "";

let hashOptions = (~algorithm=?, ~length=?, ()) =>
  hashOptions(
    ~_Algorithm=?Belt.Option.map(algorithm, hashToJs),
    ~length?,
    (),
  );

Cheers :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment