resolve stuff
This commit is contained in:
parent
dec78265a3
commit
aae64081ad
8 changed files with 59 additions and 16 deletions
|
@ -61,3 +61,4 @@ export function convertCase(value: string, convention: CaseConvention) {
|
|||
return joinMap(upper, '-', words)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
17
src/json.ts
17
src/json.ts
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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
16
src/registry.ts
Normal 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()
|
||||
|
|
@ -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']
|
||||
|
|
Loading…
Add table
Reference in a new issue