class_name DataFieldValue extends RefCounted enum DataFieldType { TEXT, MULTILINE_TEXT, NUMBER, BOOL, FORMULA, LIST } var field_type: DataFieldType var value: Variant static func _type_to_string(t: DataFieldType) -> String: match t: DataFieldType.TEXT: return "Text" DataFieldType.MULTILINE_TEXT: return "MultiText" DataFieldType.NUMBER: return "Number" DataFieldType.BOOL: return "Boolean" DataFieldType.FORMULA: return "Formula" DataFieldType.LIST: return "List" _: return str(int(t)) static func _string_to_type(s: String) -> DataFieldType: match s: "Text": return DataFieldType.TEXT "MultiText": return DataFieldType.MULTILINE_TEXT "Number": return DataFieldType.NUMBER "Boolean": return DataFieldType.BOOL "Formula": return DataFieldType.FORMULA "List": return DataFieldType.LIST _: return DataFieldType.TEXT static func _envelope_variant(v: Variant) -> Dictionary: return { "_kind": "gd-variant-b64", "data": Marshalls.raw_to_base64(var_to_bytes(v)) } static func _deenvelope_variant(d: Dictionary) -> Variant: var raw: PackedByteArray = Marshalls.base64_to_raw(d.get("data", "")) return bytes_to_var(raw) static func _serialize_list_value(v: Variant) -> Array: if v is Array: var out: Array = [] for item in v: if item is Dictionary or item is Array or item is String or item is int or item is float or item is bool or item == null: out.append(item) else: out.append(_envelope_variant(item)) return out return [] static func _deserialize_list_value(a: Array) -> Array: var out: Array = [] for item in a: if item is Dictionary and item.get("_kind") == "gd-variant-b64": out.append(_deenvelope_variant(item)) else: out.append(item) return out static func serialize_value(p_field_type: DataFieldType, v: Variant) -> Variant: match p_field_type: DataFieldType.TEXT, DataFieldType.MULTILINE_TEXT: return str(v) DataFieldType.NUMBER: if v is int or v is float: return v var s := str(v) if s.find(".") >= 0: return float(s) else: return int(s) DataFieldType.BOOL: return bool(v) DataFieldType.FORMULA: return str(v) DataFieldType.LIST: return _serialize_list_value(v) _: if v is Dictionary or v is Array or v is String or v is int or v is float or v is bool or v == null: return v return _envelope_variant(v) static func deserialize_value(p_field_type: DataFieldType, raw: Variant) -> Variant: match p_field_type: DataFieldType.TEXT, DataFieldType.MULTILINE_TEXT: return str(raw) DataFieldType.NUMBER: return raw if (raw is float or raw is int) else float(str(raw)) DataFieldType.BOOL: return bool(raw) DataFieldType.FORMULA: return str(raw) DataFieldType.LIST: return _deserialize_list_value(raw if raw is Array else []) _: if raw is Dictionary and raw.get("_kind") == "gd-variant-b64": return _deenvelope_variant(raw) return raw func to_dict() -> Dictionary: return { "field_type": _type_to_string(field_type), "value": serialize_value(field_type, value) } static func from_dict(d: Dictionary) -> DataFieldValue: var inst := DataFieldValue.new() inst.field_type = _string_to_type(d.get("field_type", "Text")) inst.value = deserialize_value(inst.field_type, d.get("value")) return inst