import { Deserialize, IDeserializer, IIterableAccess, IMapAccess } from './de' import { ISerializer, Serialize } from './ser' import { isObject, Null, PrimitivePrototype, type } from './utils' export class Registry { serializers: Map> = new Map() deserializers: Map> = new Map() registerSerialize(ctor: Function, serialize: Serialize) { this.serializers.set(ctor, serialize) } registerDeserialize(ctor: Function, deserialize: Deserialize) { this.deserializers.set(ctor, deserialize) } } export const GlobalRegistry = new Registry() export const registerSerialize = GlobalRegistry.registerSerialize.bind(GlobalRegistry) export const registerDeserialize = GlobalRegistry.registerDeserialize.bind(GlobalRegistry) function getFrom(map: Map, value: V): T { return map.get(type(value)) as T } export function getSerialize(value: U, fallback: Serialize, registry: Registry): Serialize { return getFrom(registry.serializers, value) || fallback } export function getDeserialize(value: U, fallback: Deserialize, registry: Registry): Deserialize { return getFrom(registry.deserializers, value) || fallback } registerSerialize(Boolean, (ser: ISerializer, value: U) => ser.serializeBoolean(value as boolean)) registerSerialize(String, (ser: ISerializer, value: U) => ser.serializeString(value as string)) registerSerialize(Number, (ser: ISerializer, value: U) => ser.serializeNumber(value as number)) registerSerialize(BigInt, (ser: ISerializer, value: U) => ser.serializeBigInt(value as bigint)) registerSerialize(Symbol, (ser: ISerializer, value: U) => ser.serializeSymbol(value as symbol)) registerSerialize(Null, (ser: ISerializer, _value: U) => ser.serializeNull()) registerSerialize(Object, (ser: ISerializer, value: U) => { const obj = Object.entries(value as object) const serObj = ser.serializeObject(obj.length) obj.forEach(([key, value]) => serObj.serializeEntry(key, value)) return serObj.end() }) registerSerialize(Array, (ser: ISerializer, value: U) => { const arr = value as any[] const iter = ser.serializeIterable(arr.length) arr.forEach((value: any) => iter.serializeElement(value)) return iter.end() }) registerDeserialize(Boolean, (de: IDeserializer) => de.deserializeBoolean({ visitBoolean(value: boolean) { return value } })) registerDeserialize(String, (de: IDeserializer) => de.deserializeString({ visitString(value: string) { return value } })) registerDeserialize(Number, (de: IDeserializer) => de.deserializeNumber({ visitNumber(value: number) { return value } })) registerDeserialize(BigInt, (de: IDeserializer) => de.deserializeBigInt({ visitBigInt(value: bigint) { return value } })) registerDeserialize(Symbol, (de: IDeserializer) => de.deserializeSymbol({ visitSymbol(value: symbol) { return value } })) registerDeserialize(Object, (de: IDeserializer) => de.deserializeObject({ visitObject(access: IMapAccess) { let result = {} as any for (const [key, value] of access) { result[key] = value } return result } })) registerDeserialize(Array, (de: IDeserializer) => de.deserializeIterable({ visitIterable(access: IIterableAccess) { let result = [] for (const value of access) { result.push(value) } return result } }))