wip classes
This commit is contained in:
parent
69e56d2d74
commit
5ef148193e
14 changed files with 47 additions and 10 deletions
1
dist/de/generic.d.ts
vendored
1
dist/de/generic.d.ts
vendored
|
@ -11,5 +11,6 @@ export declare class GenericVisitor<T> implements Visitor<T> {
|
|||
visitSymbol(value: symbol): T;
|
||||
visitNull(): T;
|
||||
visitObject(access: MapAccess): T;
|
||||
visitClass(name: string, value: MapAccess): T;
|
||||
visitIterable(access: IterableAccess): T;
|
||||
}
|
||||
|
|
4
dist/de/generic.js
vendored
4
dist/de/generic.js
vendored
|
@ -91,6 +91,10 @@ class GenericVisitor {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
visitClass(name, value) {
|
||||
console.log(name, '!!!!!!');
|
||||
return this.visitObject(value);
|
||||
}
|
||||
visitIterable(access) {
|
||||
const result = new Array(access.sizeHint());
|
||||
let element;
|
||||
|
|
2
dist/de/impl.js
vendored
2
dist/de/impl.js
vendored
|
@ -6,7 +6,7 @@ const generic_1 = require("./generic");
|
|||
function deserializeWith(deserializer, into, options) {
|
||||
const visitor = new generic_1.GenericVisitor();
|
||||
const target = new into();
|
||||
const obj = deserializer.deserializeObject(visitor);
|
||||
const obj = deserializer.deserializeClass(into.name, visitor);
|
||||
const newObject = {};
|
||||
for (const property in target) {
|
||||
const name = options.getPropertyName(property, options_1.Stage.Deserialize);
|
||||
|
|
2
dist/de/interface.d.ts
vendored
2
dist/de/interface.d.ts
vendored
|
@ -33,6 +33,7 @@ export interface Visitor<T> {
|
|||
visitSymbol(value: symbol): T;
|
||||
visitNull(): T;
|
||||
visitObject(value: MapAccess): T;
|
||||
visitClass(name: string, value: MapAccess): T;
|
||||
visitIterable?(value: IterableAccess): T;
|
||||
}
|
||||
export interface Deserializer {
|
||||
|
@ -44,6 +45,7 @@ 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;
|
||||
deserializeClass<T, V extends Visitor<T>>(name: string, visitor: V): T;
|
||||
deserializeIterable<T, V extends Visitor<T>>(visitor: V): T;
|
||||
}
|
||||
export interface Deserialize<T> {
|
||||
|
|
2
dist/options.d.ts
vendored
2
dist/options.d.ts
vendored
|
@ -31,7 +31,7 @@ export interface SkipOptions {
|
|||
export type CustomSerializer = <T, V, S extends Serializer<T>>(value: V, serializer: S) => T;
|
||||
export type CustomDeserializer = <T, D extends Deserializer>(deserializer: D) => T;
|
||||
export interface PropertyOptions {
|
||||
alias?: string;
|
||||
aliases?: Set<string>;
|
||||
default?: () => any;
|
||||
flatten?: boolean;
|
||||
rename?: RenameOptions | string;
|
||||
|
|
10
dist/ser/impl.js
vendored
10
dist/ser/impl.js
vendored
|
@ -17,8 +17,13 @@ function serializeEntries(serializer, value, options) {
|
|||
}
|
||||
return serializer.end();
|
||||
}
|
||||
function serializeClass(serializer, value, options) {
|
||||
const ser = serializer.serializeClass(value.constructor.name);
|
||||
return serializeEntries(ser, Object.entries(value), options);
|
||||
}
|
||||
function serializeObject(serializer, value, options) {
|
||||
return serializeEntries(serializer.serializeObject(), Object.entries(value), options);
|
||||
const ser = serializer.serializeObject();
|
||||
return serializeEntries(ser, Object.entries(value), options);
|
||||
}
|
||||
function serializeIter(serializer, value, options) {
|
||||
let state;
|
||||
|
@ -47,6 +52,9 @@ function serializeWith(serializer, value, optionsGetter = defaultOptions) {
|
|||
if ((0, utils_1.isIterable)(value) && (0, utils_1.isFunction)(serializer.serializeIterable)) {
|
||||
return serializeIter(serializer.serializeIterable(), value, options);
|
||||
}
|
||||
else if (!(0, utils_1.isPlainObject)(value)) {
|
||||
return serializeClass(serializer, value, options);
|
||||
}
|
||||
else if ((0, utils_1.isFunction)(serializer.serializeObject)) {
|
||||
return serializeObject(serializer, value, options);
|
||||
} // deliberate fallthrough when the above fail
|
||||
|
|
1
dist/ser/interface.d.ts
vendored
1
dist/ser/interface.d.ts
vendored
|
@ -17,6 +17,7 @@ interface TypeSerializer<T> {
|
|||
serializeNull(): T;
|
||||
serializeObject(): ObjectSerializer<T>;
|
||||
serializeIterable?(): IterableSerializer<T>;
|
||||
serializeClass(name: PropertyKey): ObjectSerializer<T>;
|
||||
}
|
||||
interface AnySerializer<T> {
|
||||
serializeAny?(value?: any): T;
|
||||
|
|
2
dist/ser/interface.js
vendored
2
dist/ser/interface.js
vendored
|
@ -12,7 +12,7 @@ const TypeSerializerMethods = [
|
|||
'serializeIterable',
|
||||
'serializeNull',
|
||||
'serializeObject',
|
||||
//'serializeClass',
|
||||
'serializeClass',
|
||||
];
|
||||
const AnySerializerMethods = ['serializeAny'];
|
||||
function isGenericSerializer(value) {
|
||||
|
|
|
@ -48,6 +48,12 @@ export class GenericVisitor<T> implements Visitor<T> {
|
|||
return result
|
||||
}
|
||||
|
||||
// TODO: use global registry to deserialize classes
|
||||
visitClass(name: string, access: MapAccess): T {
|
||||
console.log(name, '!!!!!!')
|
||||
return this.visitObject(access)
|
||||
}
|
||||
|
||||
visitIterable(access: IterableAccess): T {
|
||||
const result = new Array(access.sizeHint())
|
||||
let element
|
||||
|
|
|
@ -6,8 +6,12 @@ type DeserializeConstructor<T> = Deserialize<T> & { new(): Deserialize<T> }
|
|||
|
||||
export function deserializeWith<T, D extends Deserializer, E extends DeserializeConstructor<T>>(deserializer: D, into: E, options: SerdeOptions): T {
|
||||
const visitor = new GenericVisitor<T>()
|
||||
// options to figure out properties/fields during deserialization:
|
||||
// offer schema decorator
|
||||
// parse fields from javascript with acorn
|
||||
// allow no-param constructor for initialization - this is what it does now
|
||||
const target = new into()
|
||||
const obj = deserializer.deserializeObject(visitor) as any
|
||||
const obj = deserializer.deserializeClass(into.name, visitor) as any
|
||||
const newObject = {} as any
|
||||
|
||||
for (const property in target) {
|
||||
|
|
|
@ -62,6 +62,7 @@ export interface Visitor<T> {
|
|||
visitSymbol(value: symbol): T
|
||||
visitNull(): T
|
||||
visitObject(value: MapAccess): T
|
||||
visitClass(name: string, value: MapAccess): T
|
||||
visitIterable?(value: IterableAccess): T
|
||||
}
|
||||
|
||||
|
@ -74,6 +75,7 @@ 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
|
||||
deserializeClass<T, V extends Visitor<T>>(name: string, visitor: V): T
|
||||
deserializeIterable<T, V extends Visitor<T>>(visitor: V): T
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ export type CustomSerializer = <T, V, S extends Serializer<T>>(value: V, seriali
|
|||
export type CustomDeserializer = <T, D extends Deserializer>(deserializer: D) => T
|
||||
|
||||
export interface PropertyOptions {
|
||||
alias?: string
|
||||
aliases?: Set<string>
|
||||
// deserialization only
|
||||
default?: () => any
|
||||
flatten?: boolean
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { IterableSerializer, ObjectSerializer, Serializable, Serializer } from './interface'
|
||||
import { SerdeOptions, Stage } from '../options'
|
||||
import { ifNull, isFunction, isIterable, Nullable, orElse } from '../utils'
|
||||
import { ifNull, isFunction, isIterable, isPlainObject, Nullable, orElse } from '../utils'
|
||||
|
||||
const unhandledType = (serializer: any, value: any) => new TypeError(`'${serializer.constructor.name}' has no method for value type '${typeof value}'`)
|
||||
|
||||
|
@ -20,8 +20,15 @@ function serializeEntries<T, K extends string, V extends Serializable, E extends
|
|||
return serializer.end()
|
||||
}
|
||||
|
||||
function serializeClass<T, K extends string, V extends Serializable, R extends Record<K, V>>(serializer: Serializer<T>, value: R, options?: SerdeOptions) {
|
||||
const ser = serializer.serializeClass!(value.constructor.name)
|
||||
return serializeEntries(ser, Object.entries(value) as Iterable<[K, V]>, options)
|
||||
}
|
||||
|
||||
|
||||
function serializeObject<T, K extends string, V extends Serializable, R extends Record<K, V>>(serializer: Serializer<T>, value: R, options?: SerdeOptions) {
|
||||
return serializeEntries(serializer.serializeObject!(), Object.entries(value) as Iterable<[K, V]>, options)
|
||||
const ser = serializer.serializeObject!()
|
||||
return serializeEntries(ser, Object.entries(value) as Iterable<[K, V]>, options)
|
||||
}
|
||||
|
||||
function serializeIter<T, V extends Iterable<any>>(serializer: IterableSerializer<T>, value: V, options?: SerdeOptions) {
|
||||
|
@ -61,6 +68,8 @@ export function serializeWith<T>(serializer: Serializer<T>, value: Serializable,
|
|||
const options = optionsGetter(value)
|
||||
if (isIterable(value) && isFunction(serializer.serializeIterable)) {
|
||||
return serializeIter(serializer.serializeIterable(), value, options)
|
||||
} else if (!isPlainObject(value)) {
|
||||
return serializeClass(serializer, value as Record<PropertyKey, any>, options)
|
||||
} else if (isFunction(serializer.serializeObject)) {
|
||||
return serializeObject(serializer, value as Record<PropertyKey, any>, options)
|
||||
} // deliberate fallthrough when the above fail
|
||||
|
|
|
@ -21,7 +21,7 @@ const TypeSerializerMethods = [
|
|||
'serializeIterable',
|
||||
'serializeNull',
|
||||
'serializeObject',
|
||||
//'serializeClass',
|
||||
'serializeClass',
|
||||
] as const
|
||||
|
||||
interface TypeSerializer<T> {
|
||||
|
@ -34,7 +34,7 @@ interface TypeSerializer<T> {
|
|||
serializeObject(): ObjectSerializer<T>
|
||||
// serializeMap?(): ObjectSerializer<T>
|
||||
serializeIterable?(): IterableSerializer<T>
|
||||
//serializeClass(name: PropertyKey): ObjectSerializer<T>
|
||||
serializeClass(name: PropertyKey): ObjectSerializer<T>
|
||||
}
|
||||
|
||||
const AnySerializerMethods = ['serializeAny']
|
||||
|
|
Loading…
Add table
Reference in a new issue