Add support for more option types to Go conf file parsing

This commit is contained in:
Kovid Goyal
2023-03-15 15:17:38 +05:30
parent 3803d7e3c2
commit da38cb3254
3 changed files with 245 additions and 4 deletions

View File

@@ -442,8 +442,15 @@ def write_output(loc: str, defn: Definition) -> None:
f.write(f'{c}\n')
def go_type_data(parser_func: ParserFuncType, ctype: str) -> Tuple[str, str]:
def go_type_data(parser_func: ParserFuncType, ctype: str, is_multiple: bool = False) -> Tuple[str, str]:
if ctype:
if ctype == 'string':
if is_multiple:
return 'string', '[]string{val}, nil'
return 'string', 'val, nil'
if ctype.startswith('strdict_'):
_, rsep, fsep = ctype.split('_', 2)
return 'map[string]string', f'config.ParseStrDict(val, `{rsep}`, `{fsep}`)'
return f'*{ctype}', f'Parse{ctype}(val)'
p = parser_func.__name__
if p == 'int':
@@ -454,14 +461,26 @@ def go_type_data(parser_func: ParserFuncType, ctype: str) -> Tuple[str, str]:
return 'float64', 'strconv.ParseFloat(val, 10, 64)'
if p == 'to_bool':
return 'bool', 'config.StringToBool(val), nil'
if p == 'to_color':
return 'style.RGBA', 'style.ParseColor(val)'
if p == 'to_color_or_none':
return 'style.NullableColor', 'style.ParseColorOrNone(val)'
if p == 'positive_int':
return 'uint64', 'strconv.ParseUint(val, 10, 64)'
if p == 'positive_float':
return 'float64', 'config.PositiveFloat(val, 10, 64)'
if p == 'unit_float':
return 'float64', 'config.UnitFloat(val, 10, 64)'
if p == 'python_string':
return 'string', 'config.StringLiteral(val, 10, 64)'
th = get_type_hints(parser_func)
rettype = th['return']
return {int: 'int64', str: 'string', float: 'float64'}[rettype], f'{p}(val)'
def gen_go_code(defn: Definition) -> str:
lines = ['import "fmt"', 'import "strconv"', 'import "kitty/tools/config"',
'var _ = fmt.Println', 'var _ = config.StringToBool', 'var _ = strconv.Atoi']
lines = ['import "fmt"', 'import "strconv"', 'import "kitty/tools/config"', 'import "kitty/tools/utils/style"',
'var _ = fmt.Println', 'var _ = config.StringToBool', 'var _ = strconv.Atoi', 'var _ = style.ParseColor']
a = lines.append
choices = {}
go_types = {}
@@ -471,7 +490,7 @@ def gen_go_code(defn: Definition) -> str:
for option in sorted(defn.iter_all_options(), key=lambda a: natural_keys(a.name)):
name = option.name.capitalize()
if isinstance(option, MultiOption):
go_types[name], go_parsers[name] = go_type_data(option.parser_func, option.ctype)
go_types[name], go_parsers[name] = go_type_data(option.parser_func, option.ctype, True)
multiopts.add(name)
else:
defaults[name] = option.parser_func(option.defval_as_string)
@@ -497,6 +516,8 @@ def gen_go_code(defn: Definition) -> str:
a('func NewConfig() *Config {')
a('return &Config{')
from kitty.cli import serialize_as_go_string
from kitty.fast_data_types import Color
for name, pname in go_parsers.items():
if name in multiopts:
continue
@@ -507,6 +528,15 @@ def gen_go_code(defn: Definition) -> str:
dval = f'{name}_{cval(d)}' if name in choices else f'`{d}`'
elif isinstance(d, bool):
dval = repr(d).lower()
elif isinstance(d, dict):
dval = 'map[string]string{'
for k, v in d.items():
dval += f'"{serialize_as_go_string(k)}": "{serialize_as_go_string(v)}",'
dval += '}'
elif isinstance(d, Color):
dval = f'style.RGBA{{Red:{d.red}, Green: {d.green}, Blue: {d.blue}}}'
if 'NullableColor' in go_types[name]:
dval = f'style.NullableColor{{Color:{dval}}}'
else:
dval = repr(d)
a(f'{name}: {dval},')