2022-09-23 12:44:08 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
import typing
|
2022-09-23 18:22:24 +00:00
|
|
|
import tempfile
|
|
|
|
import os.path
|
|
|
|
import os
|
|
|
|
import shutil
|
|
|
|
import subprocess
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class DataType:
|
|
|
|
const_type: str
|
|
|
|
go_type: str
|
|
|
|
sig_type: str
|
|
|
|
value_type: str
|
2022-09-23 12:44:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_return_type(levels: int, dtype: str) -> str:
|
|
|
|
return ("map[string]" * levels) + dtype
|
|
|
|
|
|
|
|
|
2022-09-23 18:22:24 +00:00
|
|
|
def get_signature(levels: int, data_type: DataType) -> str:
|
2022-09-23 12:44:08 +00:00
|
|
|
return (
|
2022-09-23 18:22:24 +00:00
|
|
|
"func (c *Config) Get"
|
2022-09-23 12:44:08 +00:00
|
|
|
+ ("Map" * levels)
|
2022-09-23 18:22:24 +00:00
|
|
|
+ data_type.sig_type
|
2022-09-23 12:44:08 +00:00
|
|
|
+ "(key string) (empty "
|
2022-09-23 18:22:24 +00:00
|
|
|
+ get_return_type(levels, data_type.go_type)
|
2022-09-23 12:44:08 +00:00
|
|
|
+ ") {"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-09-23 18:22:24 +00:00
|
|
|
def get_empty_def(levels: int, data_type: DataType) -> str:
|
|
|
|
return "empty = make(" + get_return_type(levels, data_type.go_type) + ")"
|
2022-09-23 12:44:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_nested_keys(levels: int) -> str:
|
|
|
|
txt = ""
|
|
|
|
for count in range(levels):
|
2022-09-23 18:22:24 +00:00
|
|
|
txt += "[k" + str(count + 11) + "]"
|
2022-09-23 12:44:08 +00:00
|
|
|
return txt
|
|
|
|
|
|
|
|
|
2022-09-23 18:22:24 +00:00
|
|
|
def get_retval_def(levels: int, current_level: int, data_type: DataType) -> str:
|
2022-09-23 12:44:08 +00:00
|
|
|
base = "retval := make("
|
|
|
|
if current_level > 0:
|
|
|
|
base = "retval" + get_nested_keys(current_level) + " = make("
|
2022-09-23 18:22:24 +00:00
|
|
|
return base + get_return_type(levels - current_level, data_type.go_type) + ")"
|
2022-09-23 12:44:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_entries(levels: int) -> str:
|
2022-09-23 18:22:24 +00:00
|
|
|
return f"v10, ok := c.mapEnv[{levels-1}].next[key]"
|
2022-09-23 12:44:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_entry(levels: int) -> str:
|
2022-09-23 18:22:24 +00:00
|
|
|
return f"entry := c.env[v{levels + 11}.key]"
|
|
|
|
|
|
|
|
|
|
|
|
def set_value(levels: int, data_type: DataType) -> str:
|
|
|
|
return f"retval{get_nested_keys(levels + 1)} = entry.parsed.{data_type.value_type}"
|
2022-09-23 12:44:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_loop(levels: int) -> str:
|
2022-09-23 18:22:24 +00:00
|
|
|
return f"for k{levels + 11}, v{levels + 11} := range v{levels + 10}.next {{"
|
2022-09-23 12:44:08 +00:00
|
|
|
|
|
|
|
|
2022-09-23 18:22:24 +00:00
|
|
|
def get_function(file: typing.TextIO, levels: int, data_type: DataType):
|
|
|
|
print(get_signature(levels, data_type), file=file)
|
|
|
|
print(get_empty_def(levels, data_type), file=file)
|
|
|
|
print(get_retval_def(levels, 0, data_type), file=file)
|
2022-09-23 12:44:08 +00:00
|
|
|
print("if c.parsed {", file=file)
|
|
|
|
print("key = cleanKey(key)", file=file)
|
|
|
|
print(get_entries(levels), file=file)
|
2022-09-23 18:22:24 +00:00
|
|
|
print("if ok {", file=file)
|
|
|
|
for level in range(levels - 1):
|
2022-09-23 12:44:08 +00:00
|
|
|
print(get_loop(level), file=file)
|
2022-09-23 18:22:24 +00:00
|
|
|
print(get_retval_def(levels, level + 1, data_type), file=file)
|
|
|
|
print(get_loop(levels - 1), file=file)
|
|
|
|
print(get_entry(levels - 1), file=file)
|
2022-09-23 12:44:08 +00:00
|
|
|
print(
|
2022-09-23 18:22:24 +00:00
|
|
|
f"if (entry.dtype.baseType() == {data_type.const_type}.baseType()) && (entry.parsed.err == nil) {{",
|
2022-09-23 12:44:08 +00:00
|
|
|
file=file,
|
|
|
|
)
|
2022-09-23 18:22:24 +00:00
|
|
|
print(set_value(levels - 1, data_type), file=file)
|
2022-09-23 12:44:08 +00:00
|
|
|
print("} else {", file=file)
|
|
|
|
print("return", file=file)
|
2022-09-23 18:22:24 +00:00
|
|
|
print("};" * (levels + 1), file=file)
|
2022-09-23 12:44:08 +00:00
|
|
|
print("return retval", file=file)
|
|
|
|
print("}", file=file)
|
|
|
|
print("}", file=file)
|
|
|
|
print("return", file=file)
|
|
|
|
print("}", file=file)
|
|
|
|
|
|
|
|
|
2022-09-23 18:22:24 +00:00
|
|
|
def main():
|
|
|
|
data_types = [
|
|
|
|
DataType(
|
|
|
|
const_type="TypeInt", go_type="int64", sig_type="Int", value_type="intval"
|
|
|
|
),
|
|
|
|
DataType(
|
|
|
|
const_type="TypeMetric",
|
|
|
|
go_type="int64",
|
|
|
|
sig_type="Metric",
|
|
|
|
value_type="intval",
|
|
|
|
),
|
|
|
|
DataType(
|
|
|
|
const_type="TypeDuration",
|
|
|
|
go_type="time.Duration",
|
|
|
|
sig_type="Duration",
|
|
|
|
value_type="durval",
|
|
|
|
),
|
|
|
|
DataType(
|
|
|
|
const_type="TypeString",
|
|
|
|
go_type="string",
|
|
|
|
sig_type="String",
|
|
|
|
value_type="strval",
|
|
|
|
),
|
|
|
|
DataType(
|
|
|
|
const_type="TypeDirectory",
|
|
|
|
go_type="string",
|
|
|
|
sig_type="Directory",
|
|
|
|
value_type="strval",
|
|
|
|
),
|
|
|
|
DataType(
|
|
|
|
const_type="TypeBool", go_type="bool", sig_type="Bool", value_type="boolval"
|
|
|
|
),
|
|
|
|
DataType(
|
|
|
|
const_type="TypeHex", go_type="[]byte", sig_type="Hex", value_type="binval"
|
|
|
|
),
|
|
|
|
]
|
|
|
|
|
|
|
|
levels = 5
|
|
|
|
|
|
|
|
with tempfile.TemporaryDirectory() as pathname:
|
|
|
|
code_file = os.path.join(pathname, "code.go")
|
|
|
|
with open(code_file, mode="w", encoding="utf-8") as f:
|
|
|
|
print("package envconf", file=f)
|
|
|
|
print('import "time"', file=f)
|
|
|
|
print(f"type mapEnvType [{levels}]*keyLookupType", file=f)
|
|
|
|
for level in range(levels):
|
|
|
|
for data_type in data_types:
|
|
|
|
get_function(f, level + 1, data_type)
|
|
|
|
if subprocess.run(["go", "fmt", code_file], check=True).returncode == 0:
|
|
|
|
shutil.copyfile(
|
|
|
|
code_file,
|
|
|
|
os.path.join(
|
|
|
|
os.path.dirname(os.path.realpath(__file__)), "auto_generated.go"
|
|
|
|
),
|
|
|
|
follow_symlinks=False,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|