/**
* @tsplus type Case.Ops
*/
export interface CaseOps {
of: () => Case.Constructor
tagged: (tag: A["_tag"]) => Case.Constructor
}
export const Case: CaseOps = {
of: () =>
// @ts-expect-error
(args) => {
const obj = {
[Hash.sym]: hashImpl,
[Equals.sym]: equalsImpl,
[Copy.sym]: copyImpl
}
for (const k of Object.keys(args)) {
if (typeof args[k] !== "undefined") {
obj[k] = args[k]
}
}
return obj
},
tagged: (tag) =>
// @ts-expect-error
(args) => {
const obj = {
[Hash.sym]: hashImpl,
[Equals.sym]: equalsImpl,
[Copy.sym]: copyImpl,
_tag: tag
}
for (const k of Object.keys(args)) {
if (typeof args[k] !== "undefined") {
obj[k] = args[k]
}
}
return obj
}
}
function copyImpl(this: A, that: Partial): A {
const obj = {
[Hash.sym]: hashImpl,
[Equals.sym]: equalsImpl,
[Copy.sym]: copyImpl
}
for (const k of Object.keys(this)) {
if (typeof this[k] !== "undefined") {
obj[k] = this[k]
}
}
for (const k of Object.keys(that)) {
if (typeof that[k] !== "undefined") {
obj[k] = that[k]
} else {
delete obj[k]
}
}
// @ts-expect-error
return obj
}
function equalsImpl(this: A, that: Partial): boolean {
const keysA = Object.keys(this)
const keysB = Object.keys(that)
if (keysA.length !== keysB.length) {
return false
}
for (const key of keysA) {
if (!Equals.equals(this[key], that[key])) {
return false
}
}
return true
}
function hashImpl(this: A): number {
return Hash.plainObject(this)
}
/**
* @tsplus type Case
*/
export interface Case extends Equals, Copy {
}
export declare namespace Case {
export interface Constructor {
(args: Omit): A
}
}