Autogen enum <-> string boilerplate for Go
This commit is contained in:
parent
1c62a80ec1
commit
54a1cfc380
2 changed files with 148 additions and 363 deletions
|
|
@ -1,11 +1,13 @@
|
|||
#!./kitty/launcher/kitty +launch
|
||||
# License: GPLv3 Copyright: 2022, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import argparse
|
||||
import bz2
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import struct
|
||||
import subprocess
|
||||
import sys
|
||||
|
|
@ -84,6 +86,93 @@ def replace(template: str, **kw: str) -> str:
|
|||
return template
|
||||
# }}}
|
||||
|
||||
# {{{ Stringer
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def enum_parser() -> argparse.ArgumentParser:
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument('--from-string-func-name')
|
||||
return p
|
||||
|
||||
|
||||
def stringify_file(path: str) -> None:
|
||||
with open(path) as f:
|
||||
src = f.read()
|
||||
types = {}
|
||||
constant_name_maps = {}
|
||||
for m in re.finditer(r'^type +(\S+) +\S+ +// *enum *(.*?)$', src, re.MULTILINE):
|
||||
args = m.group(2)
|
||||
types[m.group(1)] = enum_parser().parse_args(args=shlex.split(args) if args else [])
|
||||
|
||||
def get_enum_def(src: str) -> None:
|
||||
type_name = q = ''
|
||||
constants = {}
|
||||
for line in src.splitlines():
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
parts = line.split()
|
||||
if not type_name:
|
||||
if len(parts) < 2 or parts[1] not in types:
|
||||
return
|
||||
type_name = parts[1]
|
||||
q = type_name + '_'
|
||||
constant_name = parts[0]
|
||||
a, sep, b = line.partition('//')
|
||||
if sep:
|
||||
string_val = b.strip()
|
||||
else:
|
||||
string_val = constant_name
|
||||
if constant_name.startswith(q):
|
||||
string_val = constant_name[len(q):]
|
||||
constants[constant_name] = serialize_as_go_string(string_val)
|
||||
if constants and type_name:
|
||||
constant_name_maps[type_name] = constants
|
||||
|
||||
for m in re.finditer(r'^const +\((.+?)^\)', src, re.MULTILINE|re.DOTALL):
|
||||
get_enum_def(m.group(1))
|
||||
|
||||
with replace_if_needed(path.replace('.go', '_stringer_generated.go')):
|
||||
print('package', os.path.basename(os.path.dirname(path)))
|
||||
print ('import "fmt"')
|
||||
print ('import "encoding/json"')
|
||||
print()
|
||||
for type_name, constant_map in constant_name_maps.items():
|
||||
print(f'func (self {type_name}) String() string ''{')
|
||||
print('switch self {')
|
||||
is_first = True
|
||||
for constant_name, string_val in constant_map.items():
|
||||
if is_first:
|
||||
print(f'default: return "{string_val}"')
|
||||
is_first = False
|
||||
else:
|
||||
print(f'case {constant_name}: return "{string_val}"')
|
||||
print('}}')
|
||||
print(f'func (self {type_name}) MarshalJSON() ([]byte, error) {{ return json.Marshal(self.String()) }}')
|
||||
fsname = types[type_name].from_string_func_name or (type_name + '_from_string')
|
||||
print(f'func {fsname}(x string) (ans {type_name}, err error) ''{')
|
||||
print('switch x {')
|
||||
for constant_name, string_val in constant_map.items():
|
||||
print(f'case "{string_val}": return {constant_name}, nil')
|
||||
print('}')
|
||||
print(f'err = fmt.Errorf("unknown value for enum {type_name}: %#v", x)')
|
||||
print('return')
|
||||
print('}')
|
||||
print(f'func (self *{type_name}) SetString(x string) error ''{')
|
||||
print(f's, err := {fsname}(x); if err == nil {{ *self = s }}; return err''}')
|
||||
print(f'func (self *{type_name}) UnmarshalJSON(data []byte) (err error)''{')
|
||||
print('var x string')
|
||||
print('if err = json.Unmarshal(data, &x); err != nil {return err}')
|
||||
print('return self.SetString(x)}')
|
||||
|
||||
|
||||
def stringify() -> None:
|
||||
for path in (
|
||||
'tools/tui/graphics/command.go',
|
||||
):
|
||||
stringify_file(path)
|
||||
# }}}
|
||||
|
||||
# Completions {{{
|
||||
|
||||
|
|
@ -760,6 +849,7 @@ def main() -> None:
|
|||
update_completion()
|
||||
update_at_commands()
|
||||
kitten_clis()
|
||||
stringify()
|
||||
print(json.dumps(changed, indent=2))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,418 +18,113 @@ import (
|
|||
var _ = fmt.Print
|
||||
|
||||
// Enums {{{
|
||||
type GRT_a int
|
||||
type GRT_a int // enum
|
||||
|
||||
const (
|
||||
GRT_action_transmit GRT_a = iota
|
||||
GRT_action_transmit_and_display
|
||||
GRT_action_query
|
||||
GRT_action_display
|
||||
GRT_action_delete
|
||||
GRT_action_frame
|
||||
GRT_action_animate
|
||||
GRT_action_compose
|
||||
GRT_action_transmit GRT_a = iota // t
|
||||
GRT_action_transmit_and_display // T
|
||||
GRT_action_query // q
|
||||
GRT_action_display // p
|
||||
GRT_action_delete // d
|
||||
GRT_action_frame // f
|
||||
GRT_action_animate // a
|
||||
GRT_action_compose // c
|
||||
)
|
||||
|
||||
func (self GRT_a) String() string {
|
||||
switch self {
|
||||
default:
|
||||
return "t"
|
||||
case GRT_action_transmit_and_display:
|
||||
return "T"
|
||||
case GRT_action_query:
|
||||
return "q"
|
||||
case GRT_action_display:
|
||||
return "p"
|
||||
case GRT_action_delete:
|
||||
return "d"
|
||||
case GRT_action_frame:
|
||||
return "f"
|
||||
case GRT_action_animate:
|
||||
return "a"
|
||||
case GRT_action_compose:
|
||||
return "c"
|
||||
}
|
||||
}
|
||||
|
||||
func GRT_a_from_string(a string) (ans GRT_a, err error) {
|
||||
switch a {
|
||||
default:
|
||||
err = fmt.Errorf("Not a valid action: %#v", a)
|
||||
case "t":
|
||||
case "T":
|
||||
ans = GRT_action_transmit_and_display
|
||||
case "q":
|
||||
ans = GRT_action_query
|
||||
case "p":
|
||||
ans = GRT_action_display
|
||||
case "d":
|
||||
ans = GRT_action_delete
|
||||
case "f":
|
||||
ans = GRT_action_frame
|
||||
case "a":
|
||||
ans = GRT_action_animate
|
||||
case "c":
|
||||
ans = GRT_action_compose
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type GRT_q int
|
||||
type GRT_q int // enum
|
||||
|
||||
const (
|
||||
GRT_quiet_noisy GRT_q = iota
|
||||
GRT_quiet_only_errors
|
||||
GRT_quiet_silent
|
||||
GRT_quiet_noisy GRT_q = iota // 0
|
||||
GRT_quiet_only_errors // 1
|
||||
GRT_quiet_silent // 2
|
||||
)
|
||||
|
||||
func (self GRT_q) String() string {
|
||||
return strconv.Itoa(int(self))
|
||||
}
|
||||
|
||||
func GRT_q_from_string(a string) (ans GRT_q, err error) {
|
||||
switch a {
|
||||
case "0":
|
||||
case "1":
|
||||
ans = GRT_quiet_only_errors
|
||||
case "2":
|
||||
ans = GRT_quiet_silent
|
||||
default:
|
||||
err = fmt.Errorf("Not a valid quiet value: %#v", a)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type GRT_f int
|
||||
type GRT_f int // enum
|
||||
|
||||
const (
|
||||
GRT_format_rgba GRT_f = iota
|
||||
GRT_format_rgb
|
||||
GRT_format_png
|
||||
GRT_format_rgba GRT_f = iota // 32
|
||||
GRT_format_rgb // 24
|
||||
GRT_format_png // 100
|
||||
)
|
||||
|
||||
func (self GRT_f) String() string {
|
||||
switch self {
|
||||
default:
|
||||
return "32"
|
||||
case GRT_format_rgb:
|
||||
return "24"
|
||||
case GRT_format_png:
|
||||
return "100"
|
||||
}
|
||||
}
|
||||
|
||||
func GRT_f_from_string(a string) (ans GRT_f, err error) {
|
||||
switch a {
|
||||
case "32":
|
||||
case "24":
|
||||
ans = GRT_format_rgb
|
||||
case "100":
|
||||
ans = GRT_format_png
|
||||
default:
|
||||
err = fmt.Errorf("Not a valid format value: %#v", a)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type GRT_t int
|
||||
type GRT_t int // enum
|
||||
|
||||
const (
|
||||
GRT_transmission_direct GRT_t = iota
|
||||
GRT_transmission_file
|
||||
GRT_transmission_tempfile
|
||||
GRT_transmission_sharedmem
|
||||
GRT_transmission_direct GRT_t = iota // d
|
||||
GRT_transmission_file // f
|
||||
GRT_transmission_tempfile // t
|
||||
GRT_transmission_sharedmem // s
|
||||
)
|
||||
|
||||
func (self GRT_t) String() string {
|
||||
switch self {
|
||||
default:
|
||||
return "d"
|
||||
case GRT_transmission_file:
|
||||
return "f"
|
||||
case GRT_transmission_tempfile:
|
||||
return "t"
|
||||
case GRT_transmission_sharedmem:
|
||||
return "s"
|
||||
}
|
||||
}
|
||||
|
||||
func GRT_t_from_string(a string) (ans GRT_t, err error) {
|
||||
switch a {
|
||||
case "d":
|
||||
case "f":
|
||||
ans = GRT_transmission_file
|
||||
case "t":
|
||||
ans = GRT_transmission_tempfile
|
||||
case "s":
|
||||
ans = GRT_transmission_sharedmem
|
||||
default:
|
||||
err = fmt.Errorf("Not a valid transmission value: %#v", a)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type GRT_o int
|
||||
type GRT_o int // enum
|
||||
|
||||
const (
|
||||
GRT_compression_none GRT_o = iota
|
||||
GRT_compression_zlib
|
||||
GRT_compression_none GRT_o = iota //
|
||||
GRT_compression_zlib // z
|
||||
)
|
||||
|
||||
func (self GRT_o) String() string {
|
||||
switch self {
|
||||
default:
|
||||
return ""
|
||||
case GRT_compression_zlib:
|
||||
return "z"
|
||||
}
|
||||
}
|
||||
|
||||
func GRT_o_from_string(a string) (ans GRT_o, err error) {
|
||||
switch a {
|
||||
case "":
|
||||
case "z":
|
||||
ans = GRT_compression_zlib
|
||||
default:
|
||||
err = fmt.Errorf("Not a valid compression value: %#v", a)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type GRT_m int
|
||||
type GRT_m int // enum
|
||||
|
||||
const (
|
||||
GRT_more_nomore GRT_m = iota
|
||||
GRT_more_more
|
||||
GRT_more_nomore GRT_m = iota // 0
|
||||
GRT_more_more // 1
|
||||
)
|
||||
|
||||
func (self GRT_m) String() string {
|
||||
return strconv.Itoa(int(self))
|
||||
}
|
||||
|
||||
func GRT_m_from_string(a string) (ans GRT_m, err error) {
|
||||
switch a {
|
||||
case "0":
|
||||
case "1":
|
||||
ans = GRT_more_more
|
||||
default:
|
||||
err = fmt.Errorf("Not a valid more value: %#v", a)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type GRT_C int
|
||||
type GRT_C int // enum
|
||||
|
||||
const (
|
||||
GRT_cursor_move GRT_C = iota
|
||||
GRT_cursor_static
|
||||
GRT_cursor_move GRT_C = iota // 0
|
||||
GRT_cursor_static // 1
|
||||
)
|
||||
|
||||
func (self GRT_C) String() string {
|
||||
return strconv.Itoa(int(self))
|
||||
}
|
||||
|
||||
func GRT_C_from_string(a string) (ans GRT_C, err error) {
|
||||
switch a {
|
||||
case "0":
|
||||
case "1":
|
||||
ans = GRT_cursor_static
|
||||
default:
|
||||
err = fmt.Errorf("Not a valid cursor movement value: %#v", a)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type GRT_U int
|
||||
type GRT_U int // enum
|
||||
|
||||
const (
|
||||
GRT_no_unicode_placeholder GRT_U = iota
|
||||
GRT_create_unicode_placeholder
|
||||
GRT_no_unicode_placeholder GRT_U = iota // 0
|
||||
GRT_create_unicode_placeholder // 1
|
||||
)
|
||||
|
||||
func (self GRT_U) String() string {
|
||||
return strconv.Itoa(int(self))
|
||||
}
|
||||
|
||||
func GRT_U_from_string(a string) (ans GRT_U, err error) {
|
||||
switch a {
|
||||
case "0":
|
||||
case "1":
|
||||
ans = GRT_create_unicode_placeholder
|
||||
default:
|
||||
err = fmt.Errorf("Not a valid cursor movement value: %#v", a)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type CompositionMode int
|
||||
type CompositionMode int // enum
|
||||
|
||||
const (
|
||||
AlphaBlend CompositionMode = iota
|
||||
Overwrite
|
||||
AlphaBlend CompositionMode = iota // 0
|
||||
Overwrite // 1
|
||||
)
|
||||
|
||||
func (self CompositionMode) String() string {
|
||||
return strconv.Itoa(int(self))
|
||||
}
|
||||
|
||||
func CompositionMode_from_string(a string) (ans CompositionMode, err error) {
|
||||
switch a {
|
||||
case "0":
|
||||
case "1":
|
||||
ans = Overwrite
|
||||
default:
|
||||
err = fmt.Errorf("Not a valid composition mode value: %#v", a)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type GRT_d int
|
||||
type GRT_d int // enum
|
||||
|
||||
const (
|
||||
GRT_delete_visible GRT_d = iota
|
||||
GRT_free_visible
|
||||
GRT_delete_visible GRT_d = iota // a
|
||||
GRT_free_visible // A
|
||||
|
||||
GRT_delete_by_id
|
||||
GRT_free_by_id
|
||||
GRT_delete_by_id // i
|
||||
GRT_free_by_id // I
|
||||
|
||||
GRT_delete_by_number
|
||||
GRT_free_by_number
|
||||
GRT_delete_by_number // n
|
||||
GRT_free_by_number // N
|
||||
|
||||
GRT_delete_by_cursor
|
||||
GRT_free_by_cursor
|
||||
GRT_delete_by_cursor // c
|
||||
GRT_free_by_cursor // C
|
||||
|
||||
GRT_delete_by_frame
|
||||
GRT_free_by_frame
|
||||
GRT_delete_by_frame // f
|
||||
GRT_free_by_frame // F
|
||||
|
||||
GRT_delete_by_cell
|
||||
GRT_free_by_cell
|
||||
GRT_delete_by_cell // p
|
||||
GRT_free_by_cell // P
|
||||
|
||||
GRT_delete_by_cell_zindex
|
||||
GRT_free_by_cell_zindex
|
||||
GRT_delete_by_cell_zindex // q
|
||||
GRT_free_by_cell_zindex // Q
|
||||
|
||||
GRT_delete_by_column
|
||||
GRT_free_by_column
|
||||
GRT_delete_by_column // x
|
||||
GRT_free_by_column // X
|
||||
|
||||
GRT_delete_by_row
|
||||
GRT_free_by_row
|
||||
GRT_delete_by_row // y
|
||||
GRT_free_by_row // Y
|
||||
|
||||
GRT_delete_by_zindex
|
||||
GRT_free_by_zindex
|
||||
GRT_delete_by_zindex // z
|
||||
GRT_free_by_zindex // Z
|
||||
)
|
||||
|
||||
func (self GRT_d) String() string {
|
||||
switch self {
|
||||
default:
|
||||
return "a"
|
||||
case GRT_free_visible:
|
||||
return "A"
|
||||
|
||||
case GRT_delete_by_id:
|
||||
return "i"
|
||||
case GRT_free_by_id:
|
||||
return "I"
|
||||
|
||||
case GRT_delete_by_number:
|
||||
return "n"
|
||||
case GRT_free_by_number:
|
||||
return "N"
|
||||
|
||||
case GRT_delete_by_cursor:
|
||||
return "c"
|
||||
case GRT_free_by_cursor:
|
||||
return "C"
|
||||
|
||||
case GRT_delete_by_frame:
|
||||
return "f"
|
||||
case GRT_free_by_frame:
|
||||
return "F"
|
||||
|
||||
case GRT_delete_by_cell:
|
||||
return "p"
|
||||
case GRT_free_by_cell:
|
||||
return "P"
|
||||
|
||||
case GRT_delete_by_cell_zindex:
|
||||
return "q"
|
||||
case GRT_free_by_cell_zindex:
|
||||
return "Q"
|
||||
|
||||
case GRT_delete_by_column:
|
||||
return "x"
|
||||
case GRT_free_by_column:
|
||||
return "X"
|
||||
|
||||
case GRT_delete_by_row:
|
||||
return "y"
|
||||
case GRT_free_by_row:
|
||||
return "Y"
|
||||
|
||||
case GRT_delete_by_zindex:
|
||||
return "z"
|
||||
case GRT_free_by_zindex:
|
||||
return "Z"
|
||||
}
|
||||
}
|
||||
|
||||
func GRT_d_from_string(a string) (ans GRT_d, err error) {
|
||||
switch a {
|
||||
case "a":
|
||||
ans = GRT_delete_visible
|
||||
case "A":
|
||||
ans = GRT_free_visible
|
||||
|
||||
case "i":
|
||||
ans = GRT_delete_by_id
|
||||
case "I":
|
||||
ans = GRT_free_by_id
|
||||
|
||||
case "n":
|
||||
ans = GRT_delete_by_number
|
||||
case "N":
|
||||
ans = GRT_free_by_number
|
||||
|
||||
case "c":
|
||||
ans = GRT_delete_by_cursor
|
||||
case "C":
|
||||
ans = GRT_free_by_cursor
|
||||
|
||||
case "f":
|
||||
ans = GRT_delete_by_frame
|
||||
case "F":
|
||||
ans = GRT_free_by_frame
|
||||
|
||||
case "p":
|
||||
ans = GRT_delete_by_cell
|
||||
case "P":
|
||||
ans = GRT_free_by_cell
|
||||
|
||||
case "q":
|
||||
ans = GRT_delete_by_cell_zindex
|
||||
case "Q":
|
||||
ans = GRT_free_by_cell_zindex
|
||||
|
||||
case "x":
|
||||
ans = GRT_delete_by_column
|
||||
case "X":
|
||||
ans = GRT_free_by_column
|
||||
|
||||
case "y":
|
||||
ans = GRT_delete_by_row
|
||||
case "Y":
|
||||
ans = GRT_free_by_row
|
||||
|
||||
case "z":
|
||||
ans = GRT_delete_by_zindex
|
||||
case "Z":
|
||||
ans = GRT_free_by_zindex
|
||||
|
||||
default:
|
||||
err = fmt.Errorf("Not a valid delete value: %#v", a)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
type GraphicsCommand struct {
|
||||
|
|
|
|||
Loading…
Reference in a new issue