Custom serialisation
Borrowing the example from Gson's
TypeAdapter
, we will create a Point
class that can revive strings like "5,8"
. Let's see how the reviver looks like:const reviver = (k, v) => Point.of(...v.split(','))
Note: a third
path
argument is forwarded by the built-in revivers, mostly to help display more informative error messages when necessary. JSON.parse(..., reviver)
would not forward a path as it is not part of the native API.With that, we are ready to create our
Point
class:class Point extends M.Base {
constructor(props) {
super(props)
this.x = () => props.x
this.y = () => props.y
}
distanceTo(point) {
const {x: x1, y: y1} = this
const {x: x2, y: y2} = point
return Math.sqrt((x2() - x1()) ** 2 + (y2() - y1()) ** 2)
}
toJSON() {
return `${this.x()},${this.y()}`
}
static of(x, y) {
return new Point({x, y})
}
static metadata() {
return Object.freeze({type: Point, reviver})
}
}
We can now use it as follows:
const pointA = M.fromJSON(Point, '"2,3"')
const pointB = Point.of(3, 4)
pointA.distanceTo(pointB)
// => 1.4142135623730951 = Math.SQRT2 ≈ √2
JSON.stringify(pointB)
// => "3,4"
Last modified 3yr ago