diff --git a/sessionzero-client/scripts/models/schema/data_field_value.gd b/sessionzero-client/scripts/models/schema/data_field_value.gd index 8bf1c57..8537318 100644 --- a/sessionzero-client/scripts/models/schema/data_field_value.gd +++ b/sessionzero-client/scripts/models/schema/data_field_value.gd @@ -13,8 +13,104 @@ enum DataFieldType { 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": field_type, - "value": value # TODO: how do we serialize an uknown type here + "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