-
-
Save bloodyowl/448e04f473bee1c5fcdb6f080e276add to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open Belt | |
type serializedValue | |
external asSerializedValue: 'a => serializedValue = "%identity" | |
type serializedComparator | |
external asSerializedComparator: 'a => serializedComparator = "%identity" | |
type serialized | |
external asSerialized: 'a => serialized = "%identity" | |
type value = [#objectId(string) | #bool(bool) | #int(int) | #float(float) | #string(string) | #null] | |
let objectId = string => #objectId(string) | |
let bool = bool => #bool(bool) | |
let int = int => #int(int) | |
let float = float => #float(float) | |
let string = string => #string(string) | |
let null = #null | |
type bsonType = [ | |
| #double | |
| #string | |
| #object | |
| #array | |
| #binData | |
| #objectId | |
| #bool | |
| #date | |
| #null | |
| #regex | |
| #javascript | |
| #int | |
| #timestamp | |
| #long | |
| #decimal | |
] | |
let serializeValue = (. value: value): serializedValue => | |
switch value { | |
| #objectId(id) => asSerializedValue({"$oid": id}) | |
| #bool(bool) => asSerializedValue(bool) | |
| #int(int) => asSerializedValue(int) | |
| #float(float) => asSerializedValue(float) | |
| #string(string) => asSerializedValue(string) | |
| #null => asSerializedValue(Js.Null.empty) | |
} | |
type regex = {regex: string, options: string} | |
type rec comparator = [ | |
| #isEqual(value) | |
| #isNotEqual(value) | |
| #isNotIn(array<value>) | |
| #isIn(array<value>) | |
| #isLowerThan(value) | |
| #isLowerThanOrEqual(value) | |
| #isGreaterThan(value) | |
| #isGreaterThanOrEqual(value) | |
| #matchesRegex(regex) | |
| #exists(bool) | |
| #elemMatch(t) | |
| #isOfType(bsonType) | |
] | |
and t = [#query(array<(string, comparator)>) | #oneOf(array<t>) | #allOf(array<t>)] | |
let isEqual = value => #isEqual(value) | |
let isNotEqual = value => #isNotEqual(value) | |
let isIn = value => #isIn(value) | |
let isNotIn = value => #isNotIn(value) | |
let isLowerThan = value => #isLowerThan(value) | |
let isLowerThanOrEqual = value => #isLowerThanOrEqual(value) | |
let isGreaterThan = value => #isGreaterThan(value) | |
let isGreaterThanOrEqual = value => #isGreaterThanOrEqual(value) | |
let matchesRegex = value => #matchesRegex(value) | |
let exists = bool => #exists(bool) | |
let elemMatch = value => #elemMatch(value) | |
let isOfType = value => #isOfType(value) | |
let query = query => #query(query) | |
let oneOf = queries => #oneOf(queries) | |
let allOf = queries => #allOf(queries) | |
let allOfOption = queries => { | |
switch queries->Array.keepMap(x => x) { | |
| [] => None | |
| [query] => Some(query) | |
| queries => Some(#allOf(queries)) | |
} | |
} | |
let rec serializeComparator = (. comparator: comparator): serializedComparator => | |
switch comparator { | |
| #isEqual(value) => asSerializedComparator(serializeValue(. value)) | |
| #isNotEqual(value) => asSerializedComparator({"$ne": serializeValue(. value)}) | |
| #isIn(value) => asSerializedComparator({"$in": value->Array.mapU(serializeValue)}) | |
| #isNotIn(value) => asSerializedComparator({"$nin": value->Array.mapU(serializeValue)}) | |
| #isLowerThan(value) => asSerializedComparator({"$lt": serializeValue(. value)}) | |
| #isLowerThanOrEqual(value) => asSerializedComparator({"$lte": serializeValue(. value)}) | |
| #isGreaterThan(value) => asSerializedComparator({"$gt": serializeValue(. value)}) | |
| #isGreaterThanOrEqual(value) => asSerializedComparator({"$gte": serializeValue(. value)}) | |
| #matchesRegex({regex, options}) => | |
asSerializedComparator({"$regex": regex, "$options": options}) | |
| #exists(value) => asSerializedComparator({"$exists": value}) | |
| #elemMatch(value) => asSerializedComparator({"$elemMatch": serialize(value)}) | |
| #isOfType(value) => asSerializedComparator({"$type": value}) | |
} | |
and makeDict = value => { | |
open Js.Dict | |
map(serializeComparator, fromArray(value)) | |
} | |
and serialize = (value: t) => { | |
switch value { | |
| #query(value) => asSerialized(makeDict(value)) | |
| #oneOf(value) => | |
asSerialized({ | |
"$or": value->Array.map(serialize), | |
}) | |
| #allOf(value) => | |
asSerialized({ | |
"$and": value->Array.map(serialize), | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment