initial work on auto generated definitions
This commit is contained in:
parent
27d793492c
commit
eef48c1d0a
113
envconf.go
113
envconf.go
@ -20,18 +20,18 @@ type cEntry struct {
|
|||||||
hasdef bool // Default value is defined
|
hasdef bool // Default value is defined
|
||||||
}
|
}
|
||||||
|
|
||||||
type keyLookupStruct struct {
|
type keyLookupType struct {
|
||||||
key string
|
key string
|
||||||
end bool
|
end bool
|
||||||
next map[string]*keyLookupStruct
|
next map[string]*keyLookupType
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kl *keyLookupStruct) setKey(parts []string, key string) {
|
func (kl *keyLookupType) setKey(parts []string, key string) {
|
||||||
if len(kl.next) == 0 {
|
if len(kl.next) == 0 {
|
||||||
kl.next = make(map[string]*keyLookupStruct)
|
kl.next = make(map[string]*keyLookupType)
|
||||||
}
|
}
|
||||||
if len(parts) > 0 {
|
if len(parts) > 0 {
|
||||||
nextLookup := new(keyLookupStruct)
|
nextLookup := new(keyLookupType)
|
||||||
nextLookup.setKey(parts[1:], key)
|
nextLookup.setKey(parts[1:], key)
|
||||||
kl.next[parts[0]] = nextLookup
|
kl.next[parts[0]] = nextLookup
|
||||||
} else {
|
} else {
|
||||||
@ -40,7 +40,7 @@ func (kl *keyLookupStruct) setKey(parts []string, key string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kl *keyLookupStruct) print() {
|
func (kl *keyLookupType) print() {
|
||||||
if kl.end {
|
if kl.end {
|
||||||
fmt.Println(kl.key)
|
fmt.Println(kl.key)
|
||||||
fmt.Println("-----------------")
|
fmt.Println("-----------------")
|
||||||
@ -52,28 +52,23 @@ func (kl *keyLookupStruct) print() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mapEnvType [5]*keyLookupType
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
parsed bool
|
parsed bool
|
||||||
env map[string]cEntry
|
env map[string]cEntry
|
||||||
mapEnvTest map[int]*keyLookupStruct
|
mapEnv mapEnvType
|
||||||
mapEnv map[string]map[string]string
|
|
||||||
mapMapEnv map[string]map[string]map[string]string
|
|
||||||
mapMapMapEnv map[string]map[string]map[string]map[string]string
|
|
||||||
mapMapMapMapEnv map[string]map[string]map[string]map[string]map[string]string
|
|
||||||
mapMapMapMapMapEnv map[string]map[string]map[string]map[string]map[string]map[string]string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConfig returns an envconf.Config that is used to read configuration from environment variables.
|
// NewConfig returns an envconf.Config that is used to read configuration from environment variables.
|
||||||
// The environment variables are stored in envconf.Config, so changes to the environment after NewConfig has been called
|
// The environment variables are stored in envconf.Config, so changes to the environment after NewConfig has been called
|
||||||
// will not be taken into account.
|
// will not be taken into account.
|
||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
levels := 5
|
|
||||||
config := new(Config)
|
config := new(Config)
|
||||||
config.parsed = false
|
config.parsed = false
|
||||||
config.env = make(map[string]cEntry)
|
config.env = make(map[string]cEntry)
|
||||||
config.mapEnvTest = make(map[int]*keyLookupStruct)
|
for level, _ := range config.mapEnv {
|
||||||
for level := 1; level <= levels; level++ {
|
config.mapEnv[level] = new(keyLookupType)
|
||||||
config.mapEnvTest[level] = new(keyLookupStruct)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range os.Environ() {
|
for _, v := range os.Environ() {
|
||||||
@ -81,7 +76,7 @@ func NewConfig() *Config {
|
|||||||
if len(splitted) == 2 {
|
if len(splitted) == 2 {
|
||||||
key := cleanKey(splitted[0])
|
key := cleanKey(splitted[0])
|
||||||
val := splitted[1]
|
val := splitted[1]
|
||||||
splitted = append(strings.Split(key, "_"), make([]string, levels, levels)...)
|
splitted = append(strings.Split(key, "_"), make([]string, len(config.mapEnv), len(config.mapEnv))...)
|
||||||
if unicode.IsLetter(getFirstRune(key)) {
|
if unicode.IsLetter(getFirstRune(key)) {
|
||||||
var entry cEntry
|
var entry cEntry
|
||||||
entry.value = val
|
entry.value = val
|
||||||
@ -90,7 +85,7 @@ func NewConfig() *Config {
|
|||||||
entry.empty = false
|
entry.empty = false
|
||||||
config.env[key] = entry
|
config.env[key] = entry
|
||||||
if len(splitted) > 1 {
|
if len(splitted) > 1 {
|
||||||
for level := 1; level <= levels; level++ {
|
for level := 1; level <= len(config.mapEnv); level++ {
|
||||||
for count := 0; count < level; count++ {
|
for count := 0; count < level; count++ {
|
||||||
parts := make([]string, level, level)
|
parts := make([]string, level, level)
|
||||||
parts[0] = strings.Trim(strings.Join(splitted[:count+1], "_"), "_")
|
parts[0] = strings.Trim(strings.Join(splitted[:count+1], "_"), "_")
|
||||||
@ -106,69 +101,11 @@ func NewConfig() *Config {
|
|||||||
if parts[len(parts)-1] == "" {
|
if parts[len(parts)-1] == "" {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
config.mapEnvTest[level].setKey(parts, key)
|
config.mapEnv[level].setKey(parts, key)
|
||||||
}
|
}
|
||||||
config.mapEnvTest[level].print()
|
config.mapEnv[level].print()
|
||||||
/*
|
|
||||||
var p0, p1, p2, p3, p4, p5 string
|
|
||||||
p0 = strings.Trim(strings.Join(splitted[:count], "_"), "_")
|
|
||||||
p1 = strings.Trim(strings.Join(splitted[count:], "_"), "_")
|
|
||||||
if len(config.mapEnv[p0]) == 0 {
|
|
||||||
config.mapEnv[p0] = make(map[string]string)
|
|
||||||
config.mapMapEnv[p0] = make(map[string]map[string]string)
|
|
||||||
config.mapMapMapEnv[p0] = make(map[string]map[string]map[string]string)
|
|
||||||
config.mapMapMapMapEnv[p0] = make(map[string]map[string]map[string]map[string]string)
|
|
||||||
config.mapMapMapMapMapEnv[p0] = make(map[string]map[string]map[string]map[string]map[string]string)
|
|
||||||
}
|
|
||||||
if p0 != "" && p1 != "" {
|
|
||||||
config.mapEnv[p0][p1] = key
|
|
||||||
}
|
|
||||||
|
|
||||||
p1 = splitted[count]
|
|
||||||
p2 = strings.Trim(strings.Join(splitted[count+1:], "_"), "_")
|
|
||||||
if len(config.mapMapEnv[p0][p1]) == 0 {
|
|
||||||
config.mapMapEnv[p0][p1] = make(map[string]string)
|
|
||||||
config.mapMapMapEnv[p0][p1] = make(map[string]map[string]string)
|
|
||||||
config.mapMapMapMapEnv[p0][p1] = make(map[string]map[string]map[string]string)
|
|
||||||
config.mapMapMapMapMapEnv[p0][p1] = make(map[string]map[string]map[string]map[string]string)
|
|
||||||
}
|
|
||||||
if p0 != "" && p1 != "" && p2 != "" {
|
|
||||||
config.mapMapEnv[p0][p1][p2] = key
|
|
||||||
}
|
|
||||||
|
|
||||||
p2 = splitted[count+1]
|
|
||||||
p3 = strings.Trim(strings.Join(splitted[count+2:], "_"), "_")
|
|
||||||
if len(config.mapMapMapEnv[p0][p1][p2]) == 0 {
|
|
||||||
config.mapMapMapEnv[p0][p1][p2] = make(map[string]string)
|
|
||||||
config.mapMapMapMapEnv[p0][p1][p2] = make(map[string]map[string]string)
|
|
||||||
config.mapMapMapMapMapEnv[p0][p1][p2] = make(map[string]map[string]map[string]string)
|
|
||||||
}
|
|
||||||
if p0 != "" && p1 != "" && p2 != "" && p3 != "" {
|
|
||||||
config.mapMapMapEnv[p0][p1][p2][p3] = key
|
|
||||||
}
|
|
||||||
|
|
||||||
p3 = splitted[count+2]
|
|
||||||
p4 = strings.Trim(strings.Join(splitted[count+3:], "_"), "_")
|
|
||||||
if len(config.mapMapMapMapEnv[p0][p1][p2][p3]) == 0 {
|
|
||||||
config.mapMapMapMapEnv[p0][p1][p2][p3] = make(map[string]string)
|
|
||||||
config.mapMapMapMapMapEnv[p0][p1][p2][p3] = make(map[string]map[string]string)
|
|
||||||
}
|
|
||||||
if p0 != "" && p1 != "" && p2 != "" && p3 != "" && p4 != "" {
|
|
||||||
config.mapMapMapMapEnv[p0][p1][p2][p3][p4] = key
|
|
||||||
}
|
|
||||||
|
|
||||||
p4 = splitted[count+3]
|
|
||||||
p5 = strings.Trim(strings.Join(splitted[count+4:], "_"), "_")
|
|
||||||
if len(config.mapMapMapMapMapEnv[p0][p1][p2][p3][p4]) == 0 {
|
|
||||||
config.mapMapMapMapMapEnv[p0][p1][p2][p3][p4] = make(map[string]string)
|
|
||||||
}
|
|
||||||
if p0 != "" && p1 != "" && p2 != "" && p3 != "" && p4 != "" && p5 != "" {
|
|
||||||
config.mapMapMapMapMapEnv[p0][p1][p2][p3][p4][p5] = key
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,12 +133,12 @@ func (c *Config) Define(key string, dtype DataType) {
|
|||||||
// Variables without a defined type will be ignored by Parse.
|
// Variables without a defined type will be ignored by Parse.
|
||||||
func (c *Config) DefineMap(key string, dtype DataType) {
|
func (c *Config) DefineMap(key string, dtype DataType) {
|
||||||
key = cleanKey(key)
|
key = cleanKey(key)
|
||||||
entries, ok := c.mapEnv[key]
|
entries, ok := c.mapEnv[0].next[key]
|
||||||
if ok {
|
if ok {
|
||||||
for _, key = range entries {
|
for _, entry := range entries.next {
|
||||||
entry := c.env[key]
|
defEntry := c.env[entry.key]
|
||||||
entry.dtype = dtype
|
defEntry.dtype = dtype
|
||||||
c.env[key] = entry
|
c.env[entry.key] = defEntry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,11 +334,11 @@ func (c *Config) getRawMap(key string, dtype DataType) (empty map[string]cValue)
|
|||||||
retval := make(map[string]cValue)
|
retval := make(map[string]cValue)
|
||||||
if c.parsed {
|
if c.parsed {
|
||||||
key = cleanKey(key)
|
key = cleanKey(key)
|
||||||
entries, ok := c.mapEnv[key]
|
entries, ok := c.mapEnv[0].next[key]
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
for k, v := range entries {
|
for k, v := range entries.next {
|
||||||
entry := c.env[v]
|
entry := c.env[v.key]
|
||||||
if (entry.dtype.baseType() == dtype.baseType()) && (entry.parsed.err == nil) {
|
if (entry.dtype.baseType() == dtype.baseType()) && (entry.parsed.err == nil) {
|
||||||
retval[k] = entry.parsed
|
retval[k] = entry.parsed
|
||||||
} else {
|
} else {
|
||||||
|
106
generate.py
Normal file
106
generate.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import typing
|
||||||
|
|
||||||
|
|
||||||
|
def get_return_type(levels: int, dtype: str) -> str:
|
||||||
|
return ("map[string]" * levels) + dtype
|
||||||
|
|
||||||
|
|
||||||
|
def get_signature(levels: int, sig_dtype: str, dtype: str) -> str:
|
||||||
|
return (
|
||||||
|
"func (c *Config) get"
|
||||||
|
+ ("Map" * levels)
|
||||||
|
+ sig_dtype
|
||||||
|
+ "(key string) (empty "
|
||||||
|
+ get_return_type(levels, dtype)
|
||||||
|
+ ") {"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_empty_def(levels: int, dtype: str) -> str:
|
||||||
|
return "empty = make(" + get_return_type(levels, dtype) + ")"
|
||||||
|
|
||||||
|
|
||||||
|
def get_nested_keys(levels: int) -> str:
|
||||||
|
txt = ""
|
||||||
|
for count in range(levels):
|
||||||
|
txt += "[k" + str(count + 10) + "]"
|
||||||
|
return txt
|
||||||
|
|
||||||
|
|
||||||
|
def get_retval_def(levels: int, current_level: int, dtype: str) -> str:
|
||||||
|
base = "retval := make("
|
||||||
|
if current_level > 0:
|
||||||
|
base = "retval" + get_nested_keys(current_level) + " = make("
|
||||||
|
return base + get_return_type(levels - current_level, dtype) + ")"
|
||||||
|
|
||||||
|
|
||||||
|
def get_entries(levels: int) -> str:
|
||||||
|
return f"v9, ok := c.mapEnv[{levels}].next[key]"
|
||||||
|
|
||||||
|
|
||||||
|
def get_entry(levels: int) -> str:
|
||||||
|
return f"entry := c.env[v{levels}.key]"
|
||||||
|
|
||||||
|
|
||||||
|
def get_loop(levels: int) -> str:
|
||||||
|
return f"for k{levels + 10}, v{levels + 10} := range v{levels + 9}.next {{"
|
||||||
|
|
||||||
|
|
||||||
|
def get_function(file: typing.TextIO, levels: int, sig_dtype: str, dtype: str):
|
||||||
|
print(get_signature(levels, sig_dtype, dtype), file=file)
|
||||||
|
print(get_empty_def(levels, dtype), file=file)
|
||||||
|
print(get_retval_def(levels, 0, dtype), file=file)
|
||||||
|
print("if c.parsed {", file=file)
|
||||||
|
print("key = cleanKey(key)", file=file)
|
||||||
|
print(get_entries(levels), file=file)
|
||||||
|
for level in range(levels):
|
||||||
|
print(get_loop(level), file=file)
|
||||||
|
print(get_retval_def(levels, level, dtype), file=file)
|
||||||
|
print(get_loop(levels), file=file)
|
||||||
|
print(get_entry(levels), file=file)
|
||||||
|
print(
|
||||||
|
"if (entry.dtype.baseType() == dtype.baseType()) && (entry.parsed.err == nil) {",
|
||||||
|
file=file,
|
||||||
|
)
|
||||||
|
print("retval[k] = entry.parsed", file=file)
|
||||||
|
print("} else {", file=file)
|
||||||
|
print("return", file=file)
|
||||||
|
print("}", file=file)
|
||||||
|
print("}", file=file)
|
||||||
|
print("return retval", file=file)
|
||||||
|
print("}", file=file)
|
||||||
|
print("}", file=file)
|
||||||
|
print("return", file=file)
|
||||||
|
print("}", file=file)
|
||||||
|
|
||||||
|
|
||||||
|
with open("generated_code.go", mode="w", encoding="utf-8") as f:
|
||||||
|
print("package envconf", file=f)
|
||||||
|
get_function(f, 3, "Int", "int64")
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# func (c *Config) getRawMap(key string, dtype DataType) (empty map[string]cValue) {
|
||||||
|
# empty = make(map[string]cValue)
|
||||||
|
# retval := make(map[string]cValue)
|
||||||
|
# if c.parsed {
|
||||||
|
# key = cleanKey(key)
|
||||||
|
# entries, ok := c.mapEnv[0].next[key]
|
||||||
|
#
|
||||||
|
# if ok {
|
||||||
|
# for k, v := range entries.next {
|
||||||
|
# entry := c.env[v.key]
|
||||||
|
# if (entry.dtype.baseType() == dtype.baseType()) && (entry.parsed.err == nil) {
|
||||||
|
# retval[k] = entry.parsed
|
||||||
|
# } else {
|
||||||
|
# return
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# return retval
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# return
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
#
|
25
generated_code.go
Normal file
25
generated_code.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
func (c *Config) getMapMapMapInt(key string) (empty map[string]map[string]map[string]int64) {
|
||||||
|
empty = make(map[string]map[string]map[string]int64)
|
||||||
|
retval := make(map[string]map[string]map[string]int64)
|
||||||
|
if c.parsed {
|
||||||
|
key = cleanKey(key)
|
||||||
|
v9, ok := c.mapEnv[3].next[key]
|
||||||
|
for k10, v10 := range v9.next {
|
||||||
|
retval := make(map[string]map[string]map[string]int64)
|
||||||
|
for k11, v11 := range v10.next {
|
||||||
|
retval[k10] = make(map[string]map[string]int64)
|
||||||
|
for k12, v12 := range v11.next {
|
||||||
|
retval[k10][k11] = make(map[string]int64)
|
||||||
|
for k13, v13 := range v12.next {
|
||||||
|
entry := c.env[v3.key]
|
||||||
|
if (entry.dtype.baseType() == dtype.baseType()) && (entry.parsed.err == nil) {
|
||||||
|
retval[k] = entry.parsed
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user