Documentation ¶
Overview ¶
Package ini provides parsing and pretty printing methods for ini config files including comments for sections and keys. The ini data can also be loaded from/to structures using struct tags.
Since there is not really a strict definition for the ini file format, this implementation follows these rules:
- a section name cannot be empty unless it is the global one
- leading and trailing whitespaces for key names are ignored
- leading whitespace for key values are ignored
- all characters from the first non whitespace to the end of the line are accepted for a value, unless the value is single or double quoted
- anything after a quoted value is ignored
- section and key names are not case sensitive by default
- in case of conflicting key names, only the last one is used
- in case of conflicting section names, only the last one is considered by default. However, if specified during initialization, the keys of conflicting sections can be merged.
Behaviour of INI processing can be modified using struct tags. The struct tags are defined by the "ini" keyword. The struct tags format is:
<key name>[,section name[,last key in a block]]
If a key name is '-' then the struct field is ignored.
Example ¶
package main import ( "fmt" "os" "time" ini "github.com/pierrec/go-ini" ) // Password holds a password in clear. // It implements encoding.TextMarshaler and encoding.TextUnmarshaler. type Password string // MarshalText obfuscates the password. func (p Password) MarshalText() ([]byte, error) { buf := []byte(p) rot13(buf) return buf, nil } // UnmarshalText unobfuscates the password. func (p *Password) UnmarshalText(buf []byte) error { rot13(buf) *p = Password(buf) return nil } func rot13(buf []byte) { for i, c := range buf { if (c >= 'A' && c < 'N') || (c >= 'a' && c < 'n') { buf[i] += 13 } else if (c > 'M' && c <= 'Z') || (c > 'm' && c <= 'z') { buf[i] -= 13 } } } type User struct { Username string `ini:"usr"` Password Password `ini:"pwd"` } // Config is the structure to hold the data found in the ini source. type Config struct { Host string `ini:"host,server"` Port int `ini:"port,server"` Enabled bool `ini:"enabled,server"` Timeout time.Duration `ini:"timeout,server"` Deadline time.Time `ini:"deadline,"` // Embedded types are supported. // If anonymous, the type name is used as the default section name. // This behaviour can be overwritten by specifying the section name // with a struct tag on the embedded type. User // As well as slices. Children []string `ini:"children,family"` Ages []int `ini:"ages,family"` } func main() { date, _ := time.Parse("15:04:05Z", "05:01:01Z") conf := &Config{ "localhost", 8080, true, 3 * time.Second, date, // Although the password is in clear, // it will be obfuscated when encoded. User{"bob the cat", "password"}, []string{"Brian", "Kelly"}, []int{3, 7}, } // Encode the configuration. if err := ini.Encode(os.Stdout, conf); err != nil { fmt.Println(err) } }
Output: deadline = 0000-01-01 05:01:01 +0000 UTC [server] host = localhost port = 8080 enabled = true timeout = 3s [User] usr = bob the cat pwd = cnffjbeq [family] children = Brian,Kelly ages = 3,7
Index ¶
- Constants
- Variables
- func Decode(r io.Reader, v interface{}) error
- func Encode(w io.Writer, v interface{}) error
- type INI
- func (ini *INI) Decode(v interface{}) error
- func (ini *INI) Del(section, key string) bool
- func (ini *INI) Encode(v interface{}) error
- func (ini *INI) Get(section, key string) string
- func (ini *INI) GetComments(section, key string) []string
- func (ini *INI) Has(section, key string) bool
- func (ini *INI) Keys(section string) []string
- func (ini *INI) ReadFrom(r io.Reader) (int64, error)
- func (ini *INI) Reset()
- func (ini *INI) Sections() []string
- func (ini *INI) Set(section, key, value string)
- func (ini *INI) SetComments(section, key string, comments ...string)
- func (ini *INI) WriteTo(w io.Writer) (int64, error)
- type Option
Examples ¶
Constants ¶
const ( // DefaultComment is the default value used to prefix comments. DefaultComment = ";" // DefaultSliceSeparator is the default slice separator used to decode and encode slices. DefaultSliceSeparator = ',' // DefaultMapKeySeparator is the default map key separator used to decode and encode slices. DefaultMapKeySeparator = ':' )
Variables ¶
var DefaultOptions []Option
DefaultOptions lists the Options for the Encode and Decode functions to use.
Functions ¶
func Decode ¶
Decode populates v with the Ini values from the Reader. DefaultOptions are used. See Ini.Decode() for more information.
Example ¶
package main import ( "bytes" "fmt" "log" ini "github.com/pierrec/go-ini" ) func main() { buf := bytes.NewBufferString(` [server] host = localhost port = 80 protos = http,https `) type config struct { Host string `ini:"host,server"` Port int `ini:"port,server"` Protocols []string `ini:"protos,server"` } var conf config err := ini.Decode(buf, &conf) if err != nil { log.Fatal(err) } fmt.Printf("%+v", conf) }
Output: {Host:localhost Port:80 Protocols:[http https]}
func Encode ¶
Encode writes the contents of v to the given Writer. DefaultOptions are used. See Ini.Encode() for more information.
Example ¶
package main import ( "bytes" "fmt" "log" ini "github.com/pierrec/go-ini" ) func main() { buf := bytes.NewBuffer(nil) type config struct { Host string `ini:"host,server"` Port int `ini:"port,server"` Protocols []string `ini:"protos,server"` } conf := &config{"localhost", 80, []string{"http", "https"}} err := ini.Encode(buf, conf) if err != nil { log.Fatal(err) } fmt.Printf("%s", buf.Bytes()) }
Output: [server] host = localhost port = 80 protos = http,https
Types ¶
type INI ¶
type INI struct {
// contains filtered or unexported fields
}
INI represents the content of an ini source.
func (*INI) Decode ¶
Decode decodes the Ini values into v, which must be a pointer to a struct. If the struct field tag has not defined the key name then the name of the field is used. The Ini section is defined as the second item in the struct tag. Supported types for the struct fields are:
- types implementing the encoding.TextUnmarshaler interface
- all signed and unsigned integers
- float32 and float64
- string
- bool
- time.Time and time.Duration
- slices of the above types
func (*INI) Del ¶
Del removes a section or key from Ini returning whether or not it did. Set the key to an empty string to remove a section.
func (*INI) Encode ¶
Encode sets Ini sections and keys according to the values defined in v. v must be a pointer to a struct.
func (*INI) Get ¶
Get fetches the key value in the given section. If the section or the key is not found an empty string is returned.
func (*INI) GetComments ¶
GetComments gets the comments for the given section or key. Use an empty key to get the section comments.
func (*INI) Has ¶
Has returns whether or not the section (if the key is empty) or the key exists for the given section.
func (*INI) ReadFrom ¶
ReadFrom populates Ini with the data read from the reader. Leading and trailing whitespaces for the key names are removed. Leading whitespaces for key values are removed. If multiple sections have the same name, by default, the last one is used. This can be overridden with the MergeSections option.
func (*INI) Reset ¶
func (ini *INI) Reset()
Reset clears all sections with their associated comments and keys. Initial Options are retained.
func (*INI) Set ¶
Set adds the key with its value to the given section. If the section does not exist it is created. Setting an empty key adds a newline for the next keys.
func (*INI) SetComments ¶
SetComments sets the comments for the given section or key. Use an empty key to set the section comments.
type Option ¶
Option allows setting various options when creating an Ini type.
func CaseSensitive ¶
func CaseSensitive() Option
CaseSensitive makes section and key names case sensitive when using the Get() or Decode() methods.
func MapKeySeparator ¶
MapKeySeparator defines the separator used to split strings when decoding or encoding a map key.
func MergeSections ¶
func MergeSections() Option
MergeSections merges sections when multiple ones are defined instead of overwriting them, in which case the last one wins. This is only relevant when the Ini is being initialized by ReadFrom.
func MergeSectionsWithComments ¶
func MergeSectionsWithComments() Option
MergeSectionsWithComments is equivalent to MergeSections but all the section comments merged.
func MergeSectionsWithLastComments ¶
func MergeSectionsWithLastComments() Option
MergeSectionsWithLastComments is equivalent to MergeSections but the section comments are set to the ones from the last section.
func SliceSeparator ¶
SliceSeparator defines the separator used to split strings when decoding into a slice/map or encoding a slice/map into a key value.