Structure encoder to key-value
- kvenc.go
/*
* Copyright Oleg Borodin <borodin@unix7.org>
*
*/
package main
import (
"encoding/json"
"fmt"
"reflect"
)
const tagName string = "mytag"
const idTagName string = "id"
type User struct {
Id int `mytag:"id" json:"id"`
Name string `mytag:"name" json:"name"`
Pass string `mytag:"pass" json:"pass"`
Phone string `mytag:"pnum" json:"pnum"`
}
func encoder(prefix string, s interface{}) map[string]string {
t := reflect.TypeOf(s)
keymap := make(map[string]string)
var id int64
for i := 0; i < t.NumField(); i++ {
tag := t.Field(i).Tag.Get(tagName)
if tag == idTagName {
r := reflect.ValueOf(s)
f := reflect.Indirect(r).Field(i)
id = f.Int()
break
}
}
for i := 0; i < t.NumField(); i++ {
tag := t.Field(i).Tag.Get(tagName)
if tag == idTagName {
continue
}
r := reflect.ValueOf(s)
f := reflect.Indirect(r).Field(i)
key := fmt.Sprintf("%s:%d:%s", prefix, id, tag)
value := f.String()
keymap[key] = value
}
return keymap
}
func decoder(prefix string, id int, keymap map[string]string, s interface{}) {
v := reflect.ValueOf(s)
i := reflect.Indirect(v)
t := i.Type()
for i := 0; i < t.NumField(); i++ {
tag := t.Field(i).Tag.Get(tagName)
if tag == idTagName {
reflect.ValueOf(s).Elem().Field(i).SetInt(int64(id))
continue
}
key := fmt.Sprintf("%s:%d:%s", prefix, id, tag)
reflect.ValueOf(s).Elem().Field(i).SetString(keymap[key])
}
}
func main() {
iuser := User{ Id: 1, Name: "qwert", Pass: "12345", Phone: "1-555-1234" }
prefix := "user"
keymap := encoder(prefix, iuser)
for key := range keymap {
value := keymap[key]
fmt.Println(key, "=", value)
}
ouser := &User{}
decoder(prefix, 1, keymap, ouser)
jsonBytes, _ := json.Marshal(ouser)
fmt.Println(string(jsonBytes))
}
//EOF
Out
$ go run kvenc.go
user:1:name = qwert
user:1:pass = 12345
user:1:pnum = 1-555-1234
{"id":1,"name":"qwert","pass":"12345","pnum":"1-555-1234"}