Skip to content

Instantly share code, notes, and snippets.

@wthorp
Created December 3, 2021 16:07
Show Gist options
  • Save wthorp/6e1496c21c2e600f810cba76f336aa8e to your computer and use it in GitHub Desktop.
Save wthorp/6e1496c21c2e600f810cba76f336aa8e to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"reflect"
"strconv"
"strings"
)
type s1 struct {
S string
I int
}
const t1 = "test 1\nbest 2\nfest 3\nvest 4"
type s2 struct {
F float32
S string
}
const t2 = "3.1415 trial\n2.7182 vile\n1.6180 vial\n6.0221 denial"
func main() {
var output1 []s1
TextToStruct(&output1, t1)
fmt.Printf("%+v\n", output1)
var output2 []s2
TextToStruct(&output2, t2)
fmt.Printf("%+v\n", output2)
}
func TextToStruct(s interface{}, text string) {
p := reflect.ValueOf(s)
if p.Kind() != reflect.Ptr {
panic("not pointer")
}
a := p.Elem()
if a.Kind() != reflect.Slice {
panic("not pointer to slice")
}
t := a.Type().Elem()
lines := strings.Split(text, "\n")
a.Set(reflect.MakeSlice(reflect.SliceOf(t), len(lines), len(lines)))
for j, line := range lines {
words := strings.Split(line, " ")
if len(words) != t.NumField() {
panic("wrong word count")
}
for i := 0; i < t.NumField(); i++ {
switch a.Index(j).Field(i).Kind() {
case reflect.String:
a.Index(j).Field(i).SetString(words[i])
case reflect.Int:
x, _ := strconv.Atoi(words[i])
a.Index(j).Field(i).SetInt(int64(x))
case reflect.Float32:
x, _ := strconv.ParseFloat(words[i], 32)
a.Index(j).Field(i).SetFloat(x)
default:
panic("unimplemented")
// I'm not sure if there's generic conversion
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment