Currently I write a rescript-d3
bindings, but I prefer make some sub-module in origin source.
D3-Time API like this
d3.timeSecond.ceil(new Date())
d3.timeMinute.ceil(new Date())
In theory i need write res file like this
module D3 = {
module TimeSecond = {
type t
@module("d3")
let timeSecond: t = "timeSecond"
@send
let ceil: (t, Js.Date.t) => Js.Date.t = "ceil"
}
module TimeMinute = {
type t
@module("d3")
let timeMinute: t = "timeMinute"
@send
let ceil: (t, Js.Date.t) => Js.Date.t = "ceil"
}
}
but i prefer write like this:
module Interval = {
type timeMillisecond
type timeSecond
@module("d3")
external timeMillisecond: timeMillisecond = "timeMillisecond"
@module("d3")
external timeSecond: timeSecond = "timeSecond"
@send
external floor: ('t, Js.Date.t) => Js.Date.t = "floor"
@send
external round: ('t, Js.Date.t) => Js.Date.t = "round"
@send
external ceil: ('t, Js.Date.t) => Js.Date.t = "ceil"
@send
external offset: ('t, Js.Date.t, option<int>) => Js.Date.t = "offset"
@send
external range: ('t, Js.Date.t, Js.Date.t, option<int>) => array<Js.Date.t> = "range"
@send
external filter: ('t, Js.Date.t => bool) => 't = "filter"
@send
external every: ('t, int) => 't = "every"
@send
external count: ('t, Js.Date.t, Js.Date.t) => int = "count"
}
This one is generic abuse, but write less duplicate code
You can achieve safety without duplication, thanks to generics. E.g.,
// D3.res
type time<'a>
type minute
type second
type millisecond
@module("d3") external timeMinute: time<minute> = "timeMinute"
@module("d3") external timeSecond: time<second> = "timeSecond"
@module("d3") external timeMillisecond: time<millisecond> = "timeMillisecond"
@send external floor: (time<_>, Js.Date.t) => Js.Date.t = "floor"
@send external ceil: (time<_>, Js.Date.t) => Js.Date.t = "ceil"
And so on.
7 Likes