package main
import (
"bufio"
"fmt"
"log"
"os"
"reflect"
"strconv"
"strings"
)
type Config struct {
Section1 Section1 `ini:"section1"`
Section2 Section2 `ini:"section2"`
}
type Section1 struct {
Key1 string `ini:"key1"`
Key2 int `ini:"key2"`
}
type Section2 struct {
Key3 float64 `ini:"key3"`
Key4 bool `ini:"key4"`
}
func fieldName(fieldName string) func(string) bool {
return func(tag string) bool {
return strings.EqualFold(tag, fieldName)
}
}
func main() {
file, err := os.Open("config.ini")
if err != nil {
log.Fatalf("Failed to open file: %v", err)
}
defer file.Close()
cfg := Config{}
scanner := bufio.NewScanner(file)
currentSection := ""
v := reflect.ValueOf(&cfg).Elem()
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" || strings.HasPrefix(line, "#") {
continue
}
if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
currentSection = strings.Trim(line, "[]")
sectionField := v.FieldByNameFunc(fieldName(currentSection))
if !sectionField.IsValid() {
log.Printf("Invalid section: %s", currentSection)
}
} else {
parts := strings.SplitN(line, "=", 2)
if len(parts) != 2 {
log.Printf("Invalid key-value pair: %s", line)
continue
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
if currentSection == "" {
log.Printf("Key-value pair found outside of any section: %s", line)
continue
}
sectionField := v.FieldByNameFunc(fieldName(currentSection))
if !sectionField.IsValid() {
log.Printf("Invalid section: %s", currentSection)
continue
}
field := sectionField.FieldByNameFunc(fieldName(key))
if !field.IsValid() {
log.Printf("Invalid key: %s", key)
continue
}
switch field.Kind() {
case reflect.String:
field.SetString(value)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
intValue, err := strconv.ParseInt(value, 10, 64)
if err != nil {
log.Printf("Failed to parse int value for key %s: %v", key, err)
continue
}
field.SetInt(intValue)
case reflect.Float32, reflect.Float64:
floatValue, err := strconv.ParseFloat(value, 64)
if err != nil {
log.Printf("Failed to parse float value for key %s: %v", key, err)
continue
}
field.SetFloat(floatValue)
case reflect.Bool:
boolValue, err := strconv.ParseBool(value)
if err != nil {
log.Printf("Failed to parse bool value for key %s: %v", key, err)
continue
}
field.SetBool(boolValue)
default:
log.Printf("Unsupported field type for key %s", key)
}
}
}
if err := scanner.Err(); err != nil {
log.Fatalf("Error while scanning file: %v", err)
}
fmt.Printf("%+v\n", cfg)
}

- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
[Section1]
key1 = value1
key2 = 100
[Section2]
key3 = 3.14
key4 = true
