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)
|
return joinMap(upper, '-', words)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ export class GenericVisitor<T> implements Visitor<T> {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
visitIterable?(access: IterableAccess): T {
|
visitIterable(access: IterableAccess): T {
|
||||||
const result = new Array(access.sizeHint())
|
const result = new Array(access.sizeHint())
|
||||||
let element
|
let element
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,8 @@ export interface Deserializer {
|
||||||
deserializeSymbol<T, V extends Visitor<T>>(visitor: V): T
|
deserializeSymbol<T, V extends Visitor<T>>(visitor: V): T
|
||||||
deserializeNull<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
|
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> {
|
export interface Deserialize<T> {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { ContainerOptions, PropertyOptions, SerdeOptions } from './options'
|
import { ContainerOptions, PropertyOptions, SerdeOptions } from './options'
|
||||||
|
import { GlobalRegistry, Registry } from './registry'
|
||||||
|
|
||||||
export const Serde = Symbol('Serde')
|
export const Serde = Symbol('Serde')
|
||||||
|
|
||||||
|
@ -42,3 +43,10 @@ export function serde(options: ContainerOptions | PropertyOptions) {
|
||||||
export function getMetadata(value: any) {
|
export function getMetadata(value: any) {
|
||||||
return value[Serde]
|
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 { DefaultIterableAccessImpl, DefaultMapAccessImpl, Deserialize, Deserializer, IterableAccess, MapAccess, Visitor } from './de'
|
||||||
|
import { GlobalRegistry, Registry } from './registry'
|
||||||
import { IterableSerializer, ObjectSerializer, Serializable, Serializer, serializeWith } from './ser'
|
import { IterableSerializer, ObjectSerializer, Serializable, Serializer, serializeWith } from './ser'
|
||||||
import { mixin, Nullable } from './utils'
|
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}')`)
|
const unexpected = (expected: string, actual: string, position: number) => new SyntaxError(`Expected ${expected} at position ${position} (got '${actual}')`)
|
||||||
|
|
||||||
export class JSONDeserializer implements Deserializer {
|
export class JSONDeserializer implements Deserializer {
|
||||||
|
private readonly registry: Registry
|
||||||
readonly buffer: StringBuffer
|
readonly buffer: StringBuffer
|
||||||
|
|
||||||
constructor(buffer: StringBuffer) {
|
constructor(buffer: StringBuffer, registry: Registry = GlobalRegistry) {
|
||||||
this.buffer = buffer
|
this.buffer = buffer
|
||||||
|
this.registry = registry
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromString(value: string): JSONDeserializer {
|
static fromString(value: string): JSONDeserializer {
|
||||||
|
@ -353,7 +356,7 @@ export class JSONDeserializer implements Deserializer {
|
||||||
case Token.Quote === byte:
|
case Token.Quote === byte:
|
||||||
return this.deserializeString(visitor)
|
return this.deserializeString(visitor)
|
||||||
case Token.LeftSquare === byte:
|
case Token.LeftSquare === byte:
|
||||||
return this.deserializeIterable!(visitor)
|
return this.deserializeIterable(visitor)
|
||||||
case Token.LeftCurly === byte:
|
case Token.LeftCurly === byte:
|
||||||
return this.deserializeObject(visitor)
|
return this.deserializeObject(visitor)
|
||||||
default:
|
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 {
|
deserializeString<T, V extends Visitor<T>>(visitor: V): T {
|
||||||
const next = this.buffer.take()
|
const next = this.buffer.take()
|
||||||
if (next.next() === Token.Quote) {
|
if (next.next() === Token.Quote) {
|
||||||
|
@ -449,7 +460,7 @@ export class JSONDeserializer implements Deserializer {
|
||||||
throw new Error('Method not implemented.')
|
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()
|
let next = this.buffer.take()
|
||||||
if (next.next() === Token.LeftSquare) {
|
if (next.next() === Token.LeftSquare) {
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { CaseConvention, convertCase } from './case'
|
||||||
import { Deserializer } from './de'
|
import { Deserializer } from './de'
|
||||||
import { Serializer } from './ser'
|
import { Serializer } from './ser'
|
||||||
import { isFunction, isNumber, isString } from './utils'
|
import { isFunction, isNumber, isString } from './utils'
|
||||||
|
import { GlobalRegistry, Registry } from './registry'
|
||||||
|
|
||||||
|
|
||||||
export interface RenameOptions {
|
export interface RenameOptions {
|
||||||
|
@ -17,14 +18,15 @@ export interface RenameAllOptions {
|
||||||
export interface ContainerOptions {
|
export interface ContainerOptions {
|
||||||
// deserialization only
|
// deserialization only
|
||||||
default?: () => any
|
default?: () => any
|
||||||
rename?: RenameOptions | string
|
|
||||||
renameAll?: RenameAllOptions | CaseConvention
|
|
||||||
// deserialization only
|
// deserialization only
|
||||||
denyUnknownFields?: boolean
|
denyUnknownFields?: boolean
|
||||||
|
expecting?: string
|
||||||
|
rename?: RenameOptions | string
|
||||||
|
renameAll?: RenameAllOptions | CaseConvention
|
||||||
|
registry?: Registry
|
||||||
tag?: string
|
tag?: string
|
||||||
content?: string
|
content?: string
|
||||||
untagged?: boolean
|
untagged?: boolean
|
||||||
expecting?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConditionalSkipOptions {
|
export interface ConditionalSkipOptions {
|
||||||
|
@ -59,8 +61,12 @@ export type Stage = typeof Stage[keyof typeof Stage]
|
||||||
|
|
||||||
export class SerdeOptions {
|
export class SerdeOptions {
|
||||||
private readonly target: any
|
private readonly target: any
|
||||||
options: ContainerOptions
|
readonly options: ContainerOptions
|
||||||
properties: Map<string, PropertyOptions>
|
readonly properties: Map<string, PropertyOptions>
|
||||||
|
|
||||||
|
get registry() {
|
||||||
|
return this.options.registry || GlobalRegistry
|
||||||
|
}
|
||||||
|
|
||||||
constructor(target: any, options: ContainerOptions = {}, properties: Map<string, PropertyOptions> = new Map()) {
|
constructor(target: any, options: ContainerOptions = {}, properties: Map<string, PropertyOptions> = new Map()) {
|
||||||
this.target = target
|
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
|
end(): T
|
||||||
}
|
}
|
||||||
|
|
||||||
//export interface ClassSerializer<T = void> {
|
export interface ClassSerializer<T = void> {
|
||||||
// serializeField<U extends Serializable>(name: PropertyKey, value: U): T
|
serializeField<U extends Serializable>(name: PropertyKey, value: U): T
|
||||||
// end(): T
|
end(): T
|
||||||
//}
|
}
|
||||||
|
|
||||||
const TypeSerializerMethods = [
|
const TypeSerializerMethods = [
|
||||||
'serializeString',
|
'serializeString',
|
||||||
|
@ -26,7 +26,7 @@ const TypeSerializerMethods = [
|
||||||
'serializeIterable',
|
'serializeIterable',
|
||||||
'serializeNull',
|
'serializeNull',
|
||||||
'serializeObject',
|
'serializeObject',
|
||||||
//'serializeInstance',
|
'serializeClass',
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
interface TypeSerializer<T> {
|
interface TypeSerializer<T> {
|
||||||
|
@ -39,7 +39,7 @@ interface TypeSerializer<T> {
|
||||||
serializeObject(): ObjectSerializer<T>
|
serializeObject(): ObjectSerializer<T>
|
||||||
// serializeMap?(): ObjectSerializer<T>
|
// serializeMap?(): ObjectSerializer<T>
|
||||||
serializeIterable?(): IterableSerializer<T>
|
serializeIterable?(): IterableSerializer<T>
|
||||||
//serializeClass?(name: PropertyKey): ClassSerializer<T>
|
serializeClass(name: PropertyKey): ClassSerializer<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
const AnySerializerMethods = ['serializeAny']
|
const AnySerializerMethods = ['serializeAny']
|
||||||
|
|
Loading…
Add table
Reference in a new issue