146 lines
4.3 KiB
TypeScript
146 lines
4.3 KiB
TypeScript
import { IterResult, Nullable } from '../utils'
|
|
|
|
export interface IMapAccess {
|
|
nextKeySeed<T, K extends Deserialize<T>>(seed: K): IteratorResult<T>
|
|
nextValueSeed<T, V extends Deserialize<T>>(seed: V): IteratorResult<T>
|
|
nextEntrySeed<TK, TV, K extends Deserialize<TK>, V extends Deserialize<TV>>(kseed: K, vseed: V): IteratorResult<[TK, TV]>
|
|
nextKey<T>(): IteratorResult<T>
|
|
nextValue<V>(): IteratorResult<V>
|
|
nextEntry<K, V>(): IteratorResult<[K, V]>
|
|
sizeHint?(): Nullable<number>
|
|
entries<T, K extends Deserialize<T>>(seed?: K): Iterator<T>
|
|
values<T, V extends Deserialize<T>>(seed?: V): Iterator<T>
|
|
entries<TK, TV, K extends Deserialize<TK>, V extends Deserialize<TV>>(kseed: K, vseed: V): Iterator<[TK, TV]>
|
|
[Symbol.iterator]<K, V>(): Iterator<[K, V]>
|
|
}
|
|
|
|
export abstract class MapAccess {
|
|
abstract nextKeySeed<T, K extends Deserialize<T>>(seed: K): IteratorResult<T>
|
|
abstract nextValueSeed<T, V extends Deserialize<T>>(seed: V): IteratorResult<T>
|
|
|
|
nextEntrySeed<TK, TV, K extends Deserialize<TK>, V extends Deserialize<TV>>(kseed: K, vseed: V): IteratorResult<[TK, TV]> {
|
|
const key = this.nextKeySeed(kseed) as IteratorResult<TK>
|
|
|
|
if (!key.done) {
|
|
const value = this.nextValueSeed(vseed) as IteratorResult<TV>
|
|
|
|
if (!value.done) {
|
|
return IterResult.Next([key.value, value.value])
|
|
}
|
|
}
|
|
|
|
return IterResult.Done()
|
|
}
|
|
|
|
abstract nextKey<T>(): IteratorResult<T>
|
|
abstract nextValue<V>(): IteratorResult<V>
|
|
|
|
nextEntry<K, V>(): IteratorResult<[K, V]> {
|
|
const key = this.nextKey() as IteratorResult<K>
|
|
|
|
if (!key.done) {
|
|
const value = this.nextValue() as IteratorResult<V>
|
|
|
|
if (!value.done) {
|
|
return IterResult.Next([key.value, value.value])
|
|
}
|
|
}
|
|
|
|
return IterResult.Done()
|
|
}
|
|
|
|
private *generate<T>(next: () => IteratorResult<T>): Iterator<T> {
|
|
let item
|
|
|
|
while ((item = next()) && !item.done) {
|
|
yield item.value
|
|
}
|
|
}
|
|
|
|
keys<T, K extends Deserialize<T>>(seed?: K): Iterator<T> {
|
|
return this.generate(
|
|
seed == null ?
|
|
this.nextKey.bind(this) :
|
|
this.nextKeySeed.bind(this, seed) as any
|
|
)
|
|
}
|
|
|
|
values<T, V extends Deserialize<T>>(seed?: V): Iterator<T> {
|
|
return this.generate(
|
|
seed == null ?
|
|
this.nextValue.bind(this) :
|
|
this.nextValueSeed.bind(this, seed) as any
|
|
)
|
|
}
|
|
|
|
entries<TK, TV, K extends Deserialize<TK>, V extends Deserialize<TV>>(kseed?: K, vseed?: V): Iterator<[TK, TV]> {
|
|
return this.generate(
|
|
kseed == null || vseed == null ?
|
|
this.nextEntry.bind(this) :
|
|
this.nextEntrySeed.bind(this, kseed, vseed) as any
|
|
)
|
|
}
|
|
|
|
[Symbol.iterator]<K, V>(): Iterator<K, V> {
|
|
return this.entries() as Iterator<K, V>
|
|
}
|
|
}
|
|
|
|
export interface IIterableAccess {
|
|
nextElement<T>(): IteratorResult<T>
|
|
sizeHint?(): Nullable<number>
|
|
[Symbol.iterator]<T>(): Iterator<T>
|
|
}
|
|
|
|
export abstract class IterableAccess implements IIterableAccess {
|
|
abstract nextElement<T>(): IteratorResult<T>
|
|
|
|
*[Symbol.iterator]<T>(): Iterator<T> {
|
|
return {
|
|
next: this.nextElement
|
|
}
|
|
}
|
|
}
|
|
|
|
const VisitorMethods = Object.freeze([
|
|
'visitBoolean',
|
|
'visitNumber',
|
|
'visitBigInt',
|
|
'visitString',
|
|
'visitSymbol',
|
|
'visitNull',
|
|
'visitObject',
|
|
'visitIterable'
|
|
] as const)
|
|
|
|
export function isVisitor<T>(visitor: any): visitor is IVisitor<T> {
|
|
return VisitorMethods.every(method => method in visitor)
|
|
}
|
|
export interface IVisitor<T> {
|
|
visitBoolean(value: boolean): T
|
|
visitNumber(value: number): T
|
|
visitBigInt(value: bigint): T
|
|
visitString(value: string): T
|
|
visitSymbol(value: symbol): T
|
|
visitNull(): T
|
|
visitObject(access: IMapAccess): T
|
|
visitIterable(access: IIterableAccess): T
|
|
}
|
|
|
|
export interface IDeserializer {
|
|
deserializeAny<T>(visitor: Partial<IVisitor<T>>): T
|
|
deserializeBoolean<T>(visitor: Partial<IVisitor<T>>): T
|
|
deserializeNumber<T>(visitor: Partial<IVisitor<T>>): T
|
|
deserializeBigInt<T>(visitor: Partial<IVisitor<T>>): T
|
|
deserializeString<T>(visitor: Partial<IVisitor<T>>): T
|
|
deserializeSymbol<T>(visitor: Partial<IVisitor<T>>): T
|
|
deserializeNull<T>(visitor: Partial<IVisitor<T>>): T
|
|
deserializeObject<T>(visitor: Partial<IVisitor<T>>): T
|
|
deserializeIterable<T>(visitor: Partial<IVisitor<T>>): T
|
|
deserializeFunction<T>(visitor: Partial<IVisitor<T>>): T
|
|
}
|
|
|
|
export interface Deserialize<T> {
|
|
(deserializer: IDeserializer): T
|
|
}
|
|
|