import { MetaContext, MetaObject } from '../../MetaContext'; import { $CLONE, $Clone, Clone } from './$clone'; export const $ASSIGN = '$assign'; export type Assign = (lhs: T, rhs: T) => T; export type $Assign = { [$ASSIGN]: Assign }; export const withAssign = MetaContext & $Clone>(MetaContextBase: TMetaContextBase) => class extends MetaContextBase { [$ASSIGN](lhs: T, rhs: T) { const $rhs = this.resolveValue(rhs); if (this.resolveValue(lhs) !== $rhs) return $rhs[$CLONE](rhs, this) as T; return $rhs[$ASSIGN](lhs, rhs, this) as T; } }; export type GenericAssign = (lhs: T, rhs: T, assignfn: Assign, clonefn: Clone, context: any) => T; export function deepAssign(genericAssign: GenericAssign) { return function $assign(this: MetaObject, lhs: T, rhs: T, context: MetaContext & $Assign & $Clone) { const assignfn = context[$ASSIGN]; const clonefn = context[$CLONE]; return (this[$ASSIGN] = function $assign(lhs: T, rhs: T, context: MetaContext) { return genericAssign(lhs, rhs, assignfn, clonefn, context); })(lhs, rhs, context); }; } export function primitiveAssign(_: T, rhs: T) { return rhs; }