diff options
Diffstat (limited to 'src/util.py')
-rw-r--r-- | src/util.py | 70 |
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 |