allow default interface impl
This commit is contained in:
parent
699a8e6a7c
commit
e213666051
1 changed files with 39 additions and 8 deletions
|
@ -1,6 +1,7 @@
|
|||
import { mix } from '../mixin.js'
|
||||
|
||||
/** @import { MixinFunction } from '../mixin.js' */
|
||||
/** @import { Fn } from './types.js' */
|
||||
|
||||
export const ProtectedConstructor = Symbol('ProtectedConstructor')
|
||||
export class ProtectedConstructorError extends Error {
|
||||
|
@ -76,6 +77,9 @@ class Method {
|
|||
/** @type {MethodType} */
|
||||
#type = MethodType.Instance
|
||||
|
||||
/** @type {Fn} */
|
||||
#implementation
|
||||
|
||||
/**
|
||||
* @param {string | Method} name
|
||||
*/
|
||||
|
@ -104,6 +108,23 @@ class Method {
|
|||
return this
|
||||
}
|
||||
|
||||
/** @param {Fn} f */
|
||||
implementation(f) {
|
||||
this.#implementation = f
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} interfaceName
|
||||
*/
|
||||
_defaultImplementation(interfaceName) {
|
||||
const err = new NotImplementedError(
|
||||
`${interfaceName}::${this.#name}`
|
||||
)
|
||||
|
||||
return function() { throw err }
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Function} target
|
||||
*/
|
||||
|
@ -120,13 +141,10 @@ class Method {
|
|||
* @param {Function} target
|
||||
*/
|
||||
implement(builder, target) {
|
||||
const err = new NotImplementedError(
|
||||
`${builder.name}::${this.#name}`
|
||||
)
|
||||
|
||||
this._getInstallationPoint(target)[this.#name] = function() {
|
||||
throw err
|
||||
}
|
||||
const impl = this.#implementation || this._defaultImplementation(builder.name)
|
||||
|
||||
this._getInstallationPoint(target)[this.#name] = impl
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,7 +214,15 @@ class Interface {
|
|||
}
|
||||
}
|
||||
|
||||
class BaseSet { }
|
||||
/** @template T*/
|
||||
class BaseSet {
|
||||
_value
|
||||
|
||||
/** @param {T} value */
|
||||
constructor(value) {
|
||||
this._value = value
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PropertyKey} key
|
||||
|
@ -301,7 +327,12 @@ export const Traversable = new Interface('Traversable')
|
|||
|
||||
export const Chain = new Interface('Chain')
|
||||
.extends(Apply)
|
||||
.specifies('chain')
|
||||
.specifies(
|
||||
Method.from('chain')
|
||||
.implementation(function(f) {
|
||||
return f(this._value)
|
||||
}))
|
||||
)
|
||||
|
||||
export const ChainRef = new Interface('ChainRec')
|
||||
.extends(Chain)
|
||||
|
|
Loading…
Add table
Reference in a new issue