From 77077168dcaa10582eb1c8f062e3d4677406a660 Mon Sep 17 00:00:00 2001 From: rowan Date: Sun, 25 May 2025 11:06:06 -0500 Subject: [PATCH] update readme --- README.md | 97 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index c3f0f3b..b8ec125 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ in more complex cases, you still won't be implementing `Serializer`/`Deserialize ```ts import { registerSerialize, registerDeserialize } from 'serde' import { ISerializer } from 'serde/ser' -import { IDeserializer, IIterableAccess } from 'serde/de' +import { forward, IDeserializer, IIterableAccess, IMapAccess } from 'serde/de' import { fromString, toString } from 'serde-json-ts' class Vector2 { @@ -113,30 +113,74 @@ class Vector2 { this.x = x this.y = y } + + static serialize(serializer: ISerializer, value: Vector2) { + const iter = serializer.serializeIterable() // returns an ISerializeIterable + iter.serializeElement(value.x) + iter.serializeElement(value.y) + return iter.end() + } + + static deserialize(deserializer: IDeserializer) { + return deserializer.deserializeIterable({ + // we could implement visitNumber here, but we'll let the default + // deserializer handle it + visitIterable(access: IIterableAccess) { + const elements = [] + + for (const item of access) { + elements.push(item as number) + } + + return new Vector2(elements[0], elements[1]) + } + }) + } +} + +class Entity { + name: string + position: Vector2 + + constructor(name: string, position: Vector2) { + this.name = name + this.position = position + } + + static serialize(serializer: ISerializer, value: Entity) { + const ser = serializer.serializeObject() + ser.serializeEntry('name', value.name) + ser.serializeEntry('position', value.position) + return ser.end() + } + + static deserialize(deserializer: IDeserializer) { + return deserializer.deserializeObject({ + visitObject(access: IMapAccess) { + let name, position + for (const [key, value] of access) { + switch (key) { + case 'name': + name = value + break + case 'position': + // forward the deserialization to Vector2 + position = forward(value as string, Vector2) + break + } + } + + return new Entity(name as string, position as Vector2) + } + }) + } } // we're registering to the global serde registry -registerSerialize(Vector2, (serializer: ISerializer, value: Vector2) => { - const iter = serializer.serializeIterable() // returns an ISerializeIterable - iter.serializeElement(value.x) - iter.serializeElement(value.y) - return iter.end() -}) - -registerDeserialize(Vector2, (deserializer: IDeserializer) => deserializer.deserializeIterable({ - // we could implement visitNumber here, but we'll let the default - // deserializer handle it - visitIterable(access: IIterableAccess) { - const elements = [] - - for (const item of access) { - elements.push(item as number) - } - - return new Vector2(elements[0], elements[1]) - } -}) -) +registerSerialize(Vector2, Vector2.serialize) +registerDeserialize(Vector2, Vector2.deserialize) +registerSerialize(Entity, Entity.serialize) +registerDeserialize(Entity, Entity.deserialize) const one = new Vector2(1, 1) const serialized = toString(one) @@ -146,5 +190,14 @@ console.log(serialized) const deserializedOne = fromString(serialized, Vector2) console.log(deserializedOne) // Vector2 { x: 1, y: 1 } + +const player = new Entity('Player', one) +const serializedPlayer = toString(player) +console.log(serializedPlayer) +// {"name":"Player","position":[1,1]} + +const deserializedPlayer = fromString(serializedPlayer, Entity) +console.log(deserializedPlayer) +// Entity { name: 'Player', position: Vector2 { x: 1, y: 1 } } ```