class_name Serde const SerializeMethod = &"serialize" const DeserializeMethod = &"deserialize" enum SerdeType { Nil, Bool, Int, Float, String, Seq, Dict, Object } static func to_serde_type(godot_type: int) -> Result: match godot_type: TYPE_NIL: return Result.ok(Result.ok(SerdeType.Nil)) TYPE_BOOL: return Result.ok(Result.ok(SerdeType.Bool)) TYPE_INT: return Result.ok(Result.ok(SerdeType.Int)) TYPE_FLOAT: return Result.ok(SerdeType.Float) TYPE_STRING: return Result.ok(SerdeType.String) TYPE_STRING_NAME: return Result.ok(SerdeType.String) TYPE_NODE_PATH: return Result.ok(SerdeType.String) TYPE_VECTOR2: return Result.ok(SerdeType.Seq) TYPE_VECTOR2I: return Result.ok(SerdeType.Seq) TYPE_VECTOR3: return Result.ok(SerdeType.Seq) TYPE_VECTOR3I: return Result.ok(SerdeType.Seq) TYPE_VECTOR4I: return Result.ok(SerdeType.Seq) TYPE_VECTOR4I: return Result.ok(SerdeType.Seq) TYPE_RECT2: return Result.ok(SerdeType.Object) TYPE_RECT2I: return Result.ok(SerdeType.Object) TYPE_AABB: return Result.ok(SerdeType.Object) TYPE_TRANSFORM2D: return Result.ok(SerdeType.Object) TYPE_BASIS: return Result.ok(SerdeType.Object) TYPE_TRANSFORM3D: return Result.ok(SerdeType.Object) TYPE_PLANE: return Result.ok(SerdeType.Object) TYPE_PROJECTION: return Result.ok(SerdeType.Object) TYPE_QUATERNION: return Result.ok(SerdeType.Seq) TYPE_COLOR: return Result.ok(SerdeType.Seq) TYPE_RID: return Result.ok(SerdeType.Int) TYPE_OBJECT: return Result.ok(SerdeType.Object) TYPE_DICTIONARY: return Result.ok(SerdeType.Dict) TYPE_ARRAY: return Result.ok(SerdeType.Seq) TYPE_PACKED_BYTE_ARRAY: return Result.ok(SerdeType.Seq) TYPE_PACKED_COLOR_ARRAY: return Result.ok(SerdeType.Seq) TYPE_PACKED_INT32_ARRAY: return Result.ok(SerdeType.Seq) TYPE_PACKED_INT64_ARRAY: return Result.ok(SerdeType.Seq) TYPE_PACKED_STRING_ARRAY: return Result.ok(SerdeType.Seq) TYPE_PACKED_FLOAT32_ARRAY: return Result.ok(SerdeType.Seq) TYPE_PACKED_FLOAT64_ARRAY: return Result.ok(SerdeType.Seq) TYPE_PACKED_VECTOR2_ARRAY: return Result.ok(SerdeType.Seq) TYPE_PACKED_VECTOR3_ARRAY: return Result.ok(SerdeType.Seq) TYPE_PACKED_VECTOR4_ARRAY: return Result.ok(SerdeType.Seq) TYPE_SIGNAL: return Result.err("Refusing to (de)serialize Signal") TYPE_CALLABLE: return Result.err("Refusing to (de)serialize Callable") _: return Result.err(Error.InvalidArgument.new(godot_type)) static func _serialize_seq(serializer: Serializer, value: Variant) -> Variant: var ser = serializer.serialize_seq(len(value)) for element in value: ser.serialize_element(element) return ser.end() static func _serialize_dict(serializer: Serializer, value: Dictionary) -> Variant: var ser: SerializeMap = serializer.serialize_dict(value.size()) for key in value.keys(): ser.serialize_entry(key, value[key]) return ser.end() static func get_object_name(value: Variant) -> Option: var name: Option = Option.none if value.has_method("get_script"): var script_name = value.get_script().get_global_name() if script_name != null: name = Option.some(script_name) if name == null and value.has_method("get_class"): var native_name = value.get_class() if native_name != null: name = Option.some(native_name) return name static func _serialize_object(serializer: Serializer, value: Variant) -> Variant: var object_name = get_object_name(value).unwrap() var ser = serializer.serialize_object(object_name, len(value.get_property_list())) ser.serialize(value) return ser.end() static func default_serialize(serializer: Serializer, value: Variant, allow_eval: bool = false) -> Variant: match to_serde_type(typeof(value)).unwrap(): SerdeType.Nil: return serializer.serialize_nil() SerdeType.Bool: return serializer.serialize_bool(value) SerdeType.Int: return serializer.serialize_int(value) SerdeType.Float: return serializer.serialize_float(value) SerdeType.String: return serializer.serialize_string(value) SerdeType.Seq: return _serialize_seq(serializer, value) SerdeType.Dict: return _serialize_dict(serializer, value) SerdeType.Object: return _serialize_object(serializer, value) return Result.err("could not deserialize type %s" % typeof(value)) static func serialize(serializer: Serializer, value: Variant, allow_eval: bool = false) -> Variant: if typeof(value) == TYPE_OBJECT and value.has_method(SerializeMethod): return value.call(serializer, value, allow_eval) else: return default_serialize(serializer, value, allow_eval) class SerializeSeq extends RefCounted: func serialize_element(element: Variant): Error.NotImplemented.raise('serialize_element') func end(): Error.NotImplemented.raise('end') class SerializeMap extends RefCounted: func serialize_key(key: Variant): Error.NotImplemented.raise('serialize_key') func serialize_value(value: Variant): Error.NotImplemented.raise('serialize_value') func end(): Error.NotImplemented.raise('end') func serialize_entry(key: Variant, value: Variant): return Result.collect_ok([serialize_key(key), serialize_value(value)]) class SerializeObject extends RefCounted: func serialize_field(name: StringName, value: Variant): Error.NotImplemented.raise('serialize_field') func serialize(object: Variant): Error.NotImplemented.raise('serialize') func end(): Error.NotImplemented.raise('end') class Serializer extends RefCounted: func serialize_nil(): Error.NotImplemented.raise('serialize_nil') func serialize_bool(_value: bool): Error.NotImplemented.raise('serialize_bool') func serialize_int(_value: int): Error.NotImplemented.raise('serialize_int') func serialize_float(_value: float): Error.NotImplemented.raise('serialize_float') func serialize_string(_value: String): Error.NotImplemented.raise('serialize_string') func serialize_seq(_len: int): Error.NotImplemented.raise('serialize_string') func serialize_dict(_len: int): Error.NotImplemented.raise('serialize_string') func serialize_object(_name: StringName, _len: int): Error.NotImplemented.raise('serialize_string') class Visitor extends RefCounted: func visit_nil(): Error.NotImplemented.raise('visit_nil') func visit_bool(_value: bool): Error.NotImplemented.raise('visit_bool') func visit_int(_value: int): Error.NotImplemented.raise('visit_int') func visit_float(_value: float): Error.NotImplemented.raise('visit_float') func visit_string(_value: String): Error.NotImplemented.raise('visit_string') func visit_seq(_access: SeqAccess): Error.NotImplemented.raise('visit_seq') func visit_dict(_access: MapAccess): Error.NotImplemented.raise('visit_dict') class GenericVisitor extends Visitor: func visit_nil(): return null func visit_bool(value: bool): print('bool', value) return value func visit_int(value: int): print('int', value) return value func visit_float(value: float): print('float', value) return value func visit_string(value: String): print('str', value) return value func visit_seq(access: SeqAccess): print('seq', access) return access.collect() func visit_dict(access: MapAccess): var a = access.collect() print('dict', a) return a class AccessIterable extends Iterator: var _next: Callable func _init(next: Callable) -> void: _next = next func next() -> Option: return _next.call().to_option().flatten() class SeqAccess extends RefCounted: func next_element(): Error.NotImplemented.raise('next_element') func iterate() -> AccessIterable: return AccessIterable.new(next_element) func collect() -> Array: var list = [] for item in iterate(): list.append(item) return list class MapAccess extends RefCounted: func next_key(): Error.NotImplemented.raise('next_key') func next_value(): Error.NotImplemented.raise('next_value') func next_entry() -> Result: var key = next_key() var val = next_value() return Result.collect_ok([key, val]) func iterate() -> AccessIterable: return AccessIterable.new(next_entry) func collect() -> Dictionary: var dict: Dictionary = {} print('collecting map') for entry in iterate(): print('entry', entry) dict.set(entry[0], entry[1]) return dict class Deserializer extends RefCounted: func deserialize_any(_visitor: Visitor): Error.NotImplemented.raise('deserialize_any') func deserialize_nil(_visitor: Visitor): Error.NotImplemented.raise('deserialize_nil') func deserialize_bool(_visitor: Visitor): Error.NotImplemented.raise('deserialize_bool') func deserialize_int(_visitor: Visitor): Error.NotImplemented.raise('deserialize_int') func deserialize_float(_visitor: Visitor): Error.NotImplemented.raise('deserialize_float') func deserialize_string(_visitor: Visitor): Error.NotImplemented.raise('deserialize_string') func deserialize_seq(_visitor: Visitor): Error.NotImplemented.raise('deserialize_seq') func deserialize_dict(_visitor: Visitor): Error.NotImplemented.raise('deserialize_dict') func deserialize_object(_name: StringName, _fields: Array[StringName], _visitor: Visitor): Error.NotImplemented.raise('deserialize_object')