flatted
3.2.73.4.2
python/flatted.py+
python/flatted.pyNew file+144
Index: package/python/flatted.py
===================================================================
--- package/python/flatted.py
+++ package/python/flatted.py
@@ -0,0 +1,144 @@
+# ISC License
+#
+# Copyright (c) 2018-2025, Andrea Giammarchi, @WebReflection
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+import json as _json
+
+class _Known:
+ def __init__(self):
+ self.key = []
+ self.value = []
+
+class _String:
+ def __init__(self, value):
+ self.value = value
+
+def _array_keys(value):
+ for i in range(len(value)):
+ yield i
+
+def _object_keys(value):
+ for key in value:
+ yield key
+
+def _is_array(value):
+ return isinstance(value, (list, tuple))
+
+def _is_object(value):
+ return isinstance(value, dict)
+
+def _is_string(value):
+ return isinstance(value, str)
+
+def _index(known, input, value):
+ input.append(value)
+ index = str(len(input) - 1)
+ known.key.append(value)
+ known.value.append(index)
+ return index
+
+def _relate(known, input, value):
+ if _is_string(value) or _is_array(value) or _is_object(value):
+ try:
+ return known.value[known.key.index(value)]
+ except:
+ return _index(known, input, value)
+
+ return value
+
+def _resolver(input, lazy, parsed):
+ def resolver(output):
+ keys = _array_keys(output) if _is_array(output) else _object_keys(output) if _is_object(output) else []
+ for key in keys:
+ value = output[key]
+ if isinstance(value, _String):
+ tmp = input[int(value.value)]
+ output[key] = tmp
+ if (_is_array(tmp) or _is_object(tmp)) and tmp not in parsed:
+ parsed.append(tmp)
+ lazy.append([output, key])
+
+ return output
+
+ return resolver
+
+def _transform(known, input, value):
+ if _is_array(value):
+ output = []
+ for val in value:
+ output.append(_relate(known, input, val))
+ return output
+
+ if _is_object(value):
+ obj = {}
+ for key in value:
+ obj[key] = _relate(known, input, value[key])
+ return obj
+
+ return value
+
+def _wrap(value):
+ if _is_string(value):
+ return _String(value)
+
+ if _is_array(value):
+ i = 0
+ for val in value:
+ value[i] = _wrap(val)
+ i += 1
+
+ elif _is_object(value):
+ for key in value:
+ value[key] = _wrap(value[key])
+
+ return value
+
+def parse(value, *args, **kwargs):
+ json = _json.loads(value, *args, **kwargs)
+ wrapped = []
+ for value in json:
+ wrapped.append(_wrap(value))
+
+ input = []
+ for value in wrapped:
+ if isinstance(value, _String):
+ input.append(value.value)
+ else:
+ input.append(value)
+
+ value = input[0]
+ lazy = []
+ revive = _resolver(input, lazy, [value])
+
+ value = revive(value)
+
+ i = 0
+ while i < len(lazy):
+ o, k = lazy[i]
+ i += 1
+ o[k] = revive(o[k])
+
+ return value
+
+
+def stringify(value, *args, **kwargs):
+ known = _Known()
+ input = []
+ output = []
+ i = int(_index(known, input, value))
+ while i < len(input):
+ output.append(_transform(known, input, input[i]))
+ i += 1
+ return _json.dumps(output, *args, **kwargs)