gitlab.com/thomasboni/go-enry/v2@v2.8.3-0.20220418031202-30b0d7a3de98/python/enry/utils.py (about) 1 from _c_enry import ffi 2 from enry.types import Guess 3 from functools import wraps 4 from typing import Hashable, List, Sequence 5 6 7 def py_bytes_to_go(py_bytes: bytes): 8 c_bytes = ffi.new("char[]", py_bytes) 9 go_slice = ffi.new("GoSlice *", [c_bytes, len(py_bytes), len(py_bytes)]) 10 return (go_slice[0], c_bytes) 11 12 13 def py_str_to_go(py_str: str): 14 str_bytes = py_str.encode() 15 c_str = ffi.new("char[]", str_bytes) 16 go_str = ffi.new("_GoString_ *", [c_str, len(str_bytes)]) 17 return (go_str[0], c_str) 18 19 20 def go_str_to_py(go_str: str): 21 str_len = go_str.n 22 if str_len > 0: 23 return ffi.unpack(go_str.p, go_str.n).decode() 24 return "" 25 26 27 def init_go_slice(): 28 return ffi.new("GoSlice *") 29 30 31 def go_str_slice_to_py(str_slice) -> List[str]: 32 slice_len = str_slice.len 33 char_arr = ffi.cast("char **", str_slice.data) 34 return [ffi.string(char_arr[i]).decode() for i in range(slice_len)] 35 36 37 def go_bool_to_py(go_bool: bool): 38 return go_bool == 1 39 40 41 def go_guess_to_py(guess) -> Guess: 42 return Guess(go_str_to_py(guess.r0), go_bool_to_py(guess.r1)) 43 44 45 py_to_go = { 46 str: py_str_to_go, 47 bytes: py_bytes_to_go, 48 } 49 50 51 go_to_py = { 52 str: go_str_to_py, 53 bool: go_bool_to_py, 54 Guess: go_guess_to_py, 55 } 56 57 58 def transform_types(in_types: Sequence[Hashable], out_type: Hashable): 59 def decorator(fn): 60 @wraps(fn) 61 def inner(*args): 62 args_transformed = [py_to_go[type_](arg) for type_, arg in zip(in_types, args)] 63 return go_to_py[out_type](fn(*(arg[0] for arg in args_transformed))) 64 return inner 65 return decorator 66 67 68 def transform_types_ret_str_slice(in_types: Sequence[Hashable]): 69 def decorator(fn): 70 @wraps(fn) 71 def inner(*args): 72 ret_slice = init_go_slice() 73 args_transformed = [py_to_go[type_](arg) for type_, arg in zip(in_types, args)] 74 fn(*(arg[0] for arg in args_transformed), ret_slice) 75 return go_str_slice_to_py(ret_slice) 76 return inner 77 return decorator