resolve stuff

This commit is contained in:
Rowan 2025-05-18 03:01:11 -05:00
parent dec78265a3
commit aae64081ad
8 changed files with 59 additions and 16 deletions

View file

@ -61,3 +61,4 @@ export function convertCase(value: string, convention: CaseConvention) {
return joinMap(upper, '-', words)
}
}

View file

@ -48,7 +48,7 @@ export class GenericVisitor<T> implements Visitor<T> {
return result
}
visitIterable?(access: IterableAccess): T {
visitIterable(access: IterableAccess): T {
const result = new Array(access.sizeHint())
let element

View file

@ -74,7 +74,8 @@ export interface Deserializer {
deserializeSymbol<T, V extends Visitor<T>>(visitor: V): T
deserializeNull<T, V extends Visitor<T>>(visitor: V): T
deserializeObject<T, V extends Visitor<T>>(visitor: V): T
deserializeIterable?<T, V extends Visitor<T>>(visitor: V): T
deserializeClass<T, V extends Visitor<T>>(name: string, fields: string[], visitor: V): T
deserializeIterable<T, V extends Visitor<T>>(visitor: V): T
}
export interface Deserialize<T> {

View file

@ -1,4 +1,5 @@
import { ContainerOptions, PropertyOptions, SerdeOptions } from './options'
import { GlobalRegistry, Registry } from './registry'
export const Serde = Symbol('Serde')
@ -42,3 +43,10 @@ export function serde(options: ContainerOptions | PropertyOptions) {
export function getMetadata(value: any) {
return value[Serde]
}
export function register(registry: Registry = GlobalRegistry) {
return function(target: any) {
registry.add(target)
return target
}
}

View file

@ -1,4 +1,5 @@
import { DefaultIterableAccessImpl, DefaultMapAccessImpl, Deserialize, Deserializer, IterableAccess, MapAccess, Visitor } from './de'
import { GlobalRegistry, Registry } from './registry'
import { IterableSerializer, ObjectSerializer, Serializable, Serializer, serializeWith } from './ser'
import { mixin, Nullable } from './utils'
@ -328,10 +329,12 @@ export class JSONSerializer implements Serializer<void> {
const unexpected = (expected: string, actual: string, position: number) => new SyntaxError(`Expected ${expected} at position ${position} (got '${actual}')`)
export class JSONDeserializer implements Deserializer {
private readonly registry: Registry
readonly buffer: StringBuffer
constructor(buffer: StringBuffer) {
constructor(buffer: StringBuffer, registry: Registry = GlobalRegistry) {
this.buffer = buffer
this.registry = registry
}
static fromString(value: string): JSONDeserializer {
@ -353,7 +356,7 @@ export class JSONDeserializer implements Deserializer {
case Token.Quote === byte:
return this.deserializeString(visitor)
case Token.LeftSquare === byte:
return this.deserializeIterable!(visitor)
return this.deserializeIterable(visitor)
case Token.LeftCurly === byte:
return this.deserializeObject(visitor)
default:
@ -386,6 +389,14 @@ export class JSONDeserializer implements Deserializer {
}
}
deserializeClass<T, V extends Visitor<T>>(name: string, fields: string[], visitor: V): T {
const cls = this.registry.get(name)
// TODO: deserialize name representing class name, use the existing deserializeWith logic
// to deserialize the class here. likely, deserialize name and then return a CommaSeparated
// object
}
deserializeString<T, V extends Visitor<T>>(visitor: V): T {
const next = this.buffer.take()
if (next.next() === Token.Quote) {
@ -449,7 +460,7 @@ export class JSONDeserializer implements Deserializer {
throw new Error('Method not implemented.')
}
deserializeIterable?<T, V extends Visitor<T>>(visitor: V): T {
deserializeIterable<T, V extends Visitor<T>>(visitor: V): T {
let next = this.buffer.take()
if (next.next() === Token.LeftSquare) {

View file

@ -2,6 +2,7 @@ import { CaseConvention, convertCase } from './case'
import { Deserializer } from './de'
import { Serializer } from './ser'
import { isFunction, isNumber, isString } from './utils'
import { GlobalRegistry, Registry } from './registry'
export interface RenameOptions {
@ -17,14 +18,15 @@ export interface RenameAllOptions {
export interface ContainerOptions {
// deserialization only
default?: () => any
rename?: RenameOptions | string
renameAll?: RenameAllOptions | CaseConvention
// deserialization only
denyUnknownFields?: boolean
expecting?: string
rename?: RenameOptions | string
renameAll?: RenameAllOptions | CaseConvention
registry?: Registry
tag?: string
content?: string
untagged?: boolean
expecting?: string
}
export interface ConditionalSkipOptions {
@ -59,8 +61,12 @@ export type Stage = typeof Stage[keyof typeof Stage]
export class SerdeOptions {
private readonly target: any
options: ContainerOptions
properties: Map<string, PropertyOptions>
readonly options: ContainerOptions
readonly properties: Map<string, PropertyOptions>
get registry() {
return this.options.registry || GlobalRegistry
}
constructor(target: any, options: ContainerOptions = {}, properties: Map<string, PropertyOptions> = new Map()) {
this.target = target

16
src/registry.ts Normal file
View file

@ -0,0 +1,16 @@
import { Constructor } from './utils'
export class Registry {
registeredClasses: Map<string, Constructor> = new Map()
add(ctor: Constructor, key: string = ctor.name) {
this.registeredClasses.set(key, ctor)
}
get(name: string) {
return this.registeredClasses.get(name)
}
}
export const GlobalRegistry = new Registry()

View file

@ -11,10 +11,10 @@ export interface IterableSerializer<T = void> {
end(): T
}
//export interface ClassSerializer<T = void> {
// serializeField<U extends Serializable>(name: PropertyKey, value: U): T
// end(): T
//}
export interface ClassSerializer<T = void> {
serializeField<U extends Serializable>(name: PropertyKey, value: U): T
end(): T
}
const TypeSerializerMethods = [
'serializeString',
@ -26,7 +26,7 @@ const TypeSerializerMethods = [
'serializeIterable',
'serializeNull',
'serializeObject',
//'serializeInstance',
'serializeClass',
] as const
interface TypeSerializer<T> {
@ -39,7 +39,7 @@ interface TypeSerializer<T> {
serializeObject(): ObjectSerializer<T>
// serializeMap?(): ObjectSerializer<T>
serializeIterable?(): IterableSerializer<T>
//serializeClass?(name: PropertyKey): ClassSerializer<T>
serializeClass(name: PropertyKey): ClassSerializer<T>
}
const AnySerializerMethods = ['serializeAny']