summaryrefslogtreecommitdiffstats
path: root/src/util.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.py')
-rw-r--r--src/util.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/util.py b/src/util.py
new file mode 100644
index 0000000..9eee425
--- /dev/null
+++ b/src/util.py
@@ -0,0 +1,70 @@
+import re
+from lark import Token
+
+# https://stackoverflow.com/a/1176023/6938271
+MIXED_2_SNAKE_CASE = re.compile(r'(?<!^)(?=[A-Z])')
+
+ENUM_EXCLUDE_ALWAYS = [
+ 'JsonValue'
+]
+
+BOXED_TYPES = [
+ 'RichText',
+ 'PageBlock'
+]
+
+STRUCT_EXCLUDE_ALWAYS = [
+ 'JsonValueNull',
+ 'JsonValueBoolean',
+ 'JsonValueNumber',
+ 'JsonValueString',
+ 'JsonValueArray',
+ 'JsonValueObject'
+]
+
+def to_snake_case(ident):
+ return MIXED_2_SNAKE_CASE.sub('_', ident).lower()
+
+def to_camel_case(ident):
+ if len(ident) == 0:
+ return ''
+ return ident[0].upper() + ident[1:]
+
+def escape_doc(doc):
+ return doc.translate(str.maketrans({"\"": '\\"', "\\": "\\\\"})).replace('\n', ' \\n')
+
+SCALAR_MAPPING = {
+ 'string': ('String', False),
+ 'int32': ('i32', False),
+ 'int53': ('i64', False),
+ 'int64': ('i64', True),
+ 'double': ('f64', False),
+ 'bytes': ('String', False),
+ 'Bool': ('bool', False),
+}
+
+def type_is_scalar(name):
+ return name in SCALAR_MAPPING
+
+def convert_scalar_name(name):
+ return SCALAR_MAPPING[name]
+
+
+def parse_param(raw_type) -> tuple: # rusty_name: str, inner: str, deserializer: Optional[int]
+ if isinstance(raw_type, Token):
+ if type_is_scalar(raw_type):
+ scalar, deserialize = convert_scalar_name(raw_type)
+ if deserialize:
+ return scalar, scalar, 0
+ else:
+ return scalar, scalar, None
+ else:
+ rusty_type = to_camel_case(raw_type)
+ if rusty_type in BOXED_TYPES:
+ return f'Box<{rusty_type}>', rusty_type, None
+ return rusty_type, rusty_type, None
+ else:
+ inner_full, inner_inner, deserializer = parse_param(raw_type.children[0])
+ if deserializer is not None:
+ deserializer += 1
+ return f'Vec<{inner_full}>', inner_inner, deserializer