Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ ini.sublime-project
ini.sublime-workspace
testdata/conf_reflect.ini
.idea
*.zip
*.rar
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -573,18 +573,18 @@ Why not?

```go
type Embeded struct {
Dates []time.Time `delim:"|"`
Dates []time.Time `delim:"|" comment:"time data"`
Places []string `ini:"places,omitempty"`
None []int `ini:",omitempty"`
}

type Author struct {
Name string `ini:"NAME"`
Male bool
Age int
Age int `comment:"Author's age"`
GPA float64
NeverMind string `ini:"-"`
*Embeded
*Embeded `comment:"Embeded section"`
}

func main() {
Expand All @@ -605,10 +605,13 @@ So, what do I get?
```ini
NAME = Unknwon
Male = true
; Author's age
Age = 21
GPA = 2.8

; Embeded section
[Embeded]
; time data
Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00
places = HangZhou,Boston
```
Expand Down
9 changes: 6 additions & 3 deletions README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -564,18 +564,18 @@ p := &Person{

```go
type Embeded struct {
Dates []time.Time `delim:"|"`
Dates []time.Time `delim:"|" comment:"time data"`
Places []string `ini:"places,omitempty"`
None []int `ini:",omitempty"`
}

type Author struct {
Name string `ini:"NAME"`
Male bool
Age int
Age int `comment:"Author's age"`
GPA float64
NeverMind string `ini:"-"`
*Embeded
*Embeded `comment:"Embeded section"`
}

func main() {
Expand All @@ -596,10 +596,13 @@ func main() {
```ini
NAME = Unknwon
Male = true
; Author's age
Age = 21
GPA = 2.8

; Embeded section
[Embeded]
; time data
Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00
places = HangZhou,Boston
```
Expand Down
79 changes: 79 additions & 0 deletions helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package ini

import (
"os"
"path/filepath"
"reflect"
"strings"
"sync"

"github.com/henrylee2cn/goutil"
"github.com/henrylee2cn/goutil/errors"
)

// SyncINI quickly create your own configuration files.
// Struct tags reference `https://github.com/henrylee2cn/ini`
func SyncINI(structPtr interface{}, f func(onecUpdateFunc func() error) error, filename ...string) error {
t := reflect.TypeOf(structPtr)
if t.Kind() != reflect.Ptr {
return errors.New("SyncINI's param must be struct pointer type.")
}
t = t.Elem()
if t.Kind() != reflect.Struct {
return errors.New("SyncINI's param must be struct pointer type.")
}

var fname string
if len(filename) > 0 {
fname = filename[0]
} else {
fname = strings.TrimSuffix(t.Name(), "Config")
fname = strings.TrimSuffix(fname, "INI")
fname = goutil.SnakeString(fname) + ".ini"
}
var cfg *File
var err error
var existed bool
cfg, err = Load(fname)
if err != nil {
os.MkdirAll(filepath.Dir(fname), 0777)
cfg, err = LooseLoad(fname)
if err != nil {
return err
}
} else {
existed = true
}

err = cfg.MapTo(structPtr)
if err != nil {
return err
}

var once sync.Once
var onecUpdateFunc = func() error {
var err error
once.Do(func() {
err = cfg.ReflectFrom(structPtr)
if err != nil {
return
}
err = cfg.SaveTo(fname)
if err != nil {
return
}
})
return err
}

if f != nil {
if err = f(onecUpdateFunc); err != nil {
return err
}
}

if !existed {
return onecUpdateFunc()
}
return nil
}
4 changes: 4 additions & 0 deletions ini.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,8 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
if len(sec.Comment) > 0 {
if sec.Comment[0] != '#' && sec.Comment[0] != ';' {
sec.Comment = "; " + sec.Comment
} else {
sec.Comment = sec.Comment[:1] + " " + strings.TrimSpace(sec.Comment[1:])
}
if _, err = buf.WriteString(sec.Comment + LineBreak); err != nil {
return 0, err
Expand Down Expand Up @@ -468,6 +470,8 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
}
if key.Comment[0] != '#' && key.Comment[0] != ';' {
key.Comment = "; " + key.Comment
} else {
key.Comment = key.Comment[:1] + " " + strings.TrimSpace(key.Comment[1:])
}
if _, err = buf.WriteString(key.Comment + LineBreak); err != nil {
return 0, err
Expand Down
18 changes: 17 additions & 1 deletion struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,11 @@ func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim
case reflect.Bool:
key.SetValue(fmt.Sprint(field.Bool()))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
key.SetValue(fmt.Sprint(field.Int()))
if t.String() == "time.Duration" {
key.SetValue(field.Interface().(time.Duration).String())
} else {
key.SetValue(fmt.Sprint(field.Int()))
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
key.SetValue(fmt.Sprint(field.Uint()))
case reflect.Float32, reflect.Float64:
Expand Down Expand Up @@ -450,6 +454,12 @@ func (s *Section) reflectFrom(val reflect.Value) error {
// Note: fieldName can never be empty here, ignore error.
sec, _ = s.f.NewSection(fieldName)
}

// add comment from comment tag
if len(sec.Comment) == 0 {
sec.Comment = tpField.Tag.Get("comment")
}

if err = sec.reflectFrom(field); err != nil {
return fmt.Errorf("error reflecting field (%s): %v", fieldName, err)
}
Expand All @@ -461,6 +471,12 @@ func (s *Section) reflectFrom(val reflect.Value) error {
if err != nil {
key, _ = s.NewKey(fieldName, "")
}

// add comment from comment tag
if len(key.Comment) == 0 {
key.Comment = tpField.Tag.Get("comment")
}

if err = reflectWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil {
return fmt.Errorf("error reflecting field (%s): %v", fieldName, err)
}
Expand Down