123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- package main
- import (
- "bytes"
- "fmt"
- "git.giaever.org/joachimmg/go-ini.git/ini"
- "io"
- "strings"
- "time"
- )
- type App struct {
- Name string
- Url string
- Scheme string
- }
- func m1() {
- // Set some data into the struct
- settings := &App{
- Name: "My Application",
- Url: "localhost",
- Scheme: "https",
- }
- // Read struct and format to INI
- idata, err := ini.Marshal(settings)
- if err != nil {
- fmt.Println("An error occured", err)
- return
- }
- // Save here? No errors.
- fmt.Println(string(idata))
- }
- func m2() {
- // Same as output from m1,
- // but we're now reading this and filling the struct
- idata := `
- Name = My Application
- Url = localhost
- Scheme = https`
- settings := &App{}
- // Must make idata from string to []byte
- if err := ini.Unmarshal([]byte(idata), settings); err != nil {
- fmt.Println("An error occured", err)
- return
- }
- // User setting here.
- fmt.Println(settings, settings.Name)
- }
- // AccessLevel type (easier to transform into text)
- type AccessLevel int
- // Make some access levels
- const (
- Admin AccessLevel = 1 << iota
- User
- Guest
- Unknown
- )
- // String returns the text representation
- func (a AccessLevel) String() string {
- switch a {
- case Admin:
- return "ADMIN"
- case User:
- return "USER"
- case Guest:
- return "GUEST"
- default:
- return "UNKNOWN"
- }
- }
- // We must be able to restore the numeric value
- func (a *AccessLevel) SetAccessLevel(al string) {
- for i := 1; AccessLevel(i) != Unknown; i = i << 1 {
- if AccessLevel(i).String() == al {
- *a = AccessLevel(i)
- return
- }
- }
- *a = Unknown
- }
- // Person defines an user
- type Person struct {
- Name string
- Birth ini.Date
- Access AccessLevel
- }
- // MarshalINI to get the ini-format of one person
- func (p *Person) MarshalINI() ([]byte, error) {
- // Uses ini.Date own marshaller method (see: types.go)
- b, err := p.Birth.MarshalINI()
- if err != nil {
- return nil, err
- }
- // Format: <name>|<ini.Date>|<access level>, e.g my name|1985-09-85-UTC-0
- return []byte(fmt.Sprintf("%s|%s|%s", string(p.Name), string(b), p.Access.String())), nil
- }
- // UnmarshalINI reads the format produces by MarshalINI
- // and creates the person/user again
- func (p *Person) UnmarshalINI(b []byte) error {
- // Split <name>|<ini.Date>|<access level>(see MarshalINI above for format)
- spl := strings.Split(string(b), "|")
- // Do some form of validation (remember: this is just an example!)
- if len(spl) != 3 {
- return fmt.Errorf("Invalid format. Expected <name|birth.ini.Date>|<AccessLevel>. Got %s", string(b))
- }
- // Set name
- p.Name = spl[0]
- // Uses trimspace here to ensure that the trailing \n (newline) is removed
- // as this is last item in <name>|<ini.Date>|<access level>
- p.Access.SetAccessLevel(strings.TrimSpace(spl[2]))
- // And use ini.Date's own unmarshaller method (see: types.go)
- return p.Birth.UnmarshalINI([]byte(spl[1]))
- }
- // Persons is several persons
- type Persons []Person
- // Personell is users with given access levels
- type Personell struct {
- Users Persons
- }
- func (p *Persons) MarshalINI() ([]byte, error) {
- // []string to store each person in
- var persons []string
- for i := 0; i < len(*p); i++ {
- // Run marshaller method on each (see Person.Marshal() above)
- person, err := (*p)[i].MarshalINI()
- // Ensure there arent any errors...
- if err != nil {
- return nil, err
- }
- // Add the person visual representation to the list of persons
- persons = append(persons, string(person))
- }
- // Return as a multiline ini-entry
- return []byte(strings.Join(persons, "\\\n")), nil
- }
- // This is left for the reader to solve ;)
- func (p *Persons) UnmarshalINI(b []byte) error {
- persons := bytes.NewBuffer(b)
- for pbytes, err := persons.ReadBytes('\n'); err == nil; pbytes, err = persons.ReadBytes('\n') {
- var person Person
- person.UnmarshalINI(pbytes)
- *p = append(*p, person)
- if err == io.EOF {
- break
- }
- }
- return nil
- }
- func m3() {
- p := &Personell{}
- // Fill some data!
- p.Users = append(p.Users,
- Person{
- Name: "Testing Johanson",
- Birth: ini.Date{time.Date(1985, time.Month(9), 23, 0, 0, 0, 0, time.UTC)},
- Access: Admin, // Admin
- },
- Person{
- Name: "Testing Aniston",
- Birth: ini.Date{time.Date(1987, time.Month(1), 12, 0, 0, 0, 0, time.UTC)},
- Access: User, // Unknown user
- },
- Person{
- Name: "Testing Cubain",
- Birth: ini.Date{time.Date(1986, time.Month(3), 3, 0, 0, 0, 0, time.UTC)},
- Access: Guest, // Guest
- },
- )
- idata, err := ini.Marshal(p)
- if err != nil {
- fmt.Println(err)
- return
- }
- fmt.Println(string(idata))
- }
- func m4() {
- // Output from m3
- idata := `
- Users = Testing Johanson|1985-9-23-UTC-0|ADMIN\
- Testing Aniston|1987-1-12-UTC-0|USER\
- Testing Cubain|1986-3-3-UTC-0|GUEST`
- p := &Personell{}
- if err := ini.Unmarshal([]byte(idata), p); err != nil {
- fmt.Println(err)
- return
- }
- fmt.Println("Success, you did it!", p)
- }
- func main() {
- m1()
- m2()
- m3()
- m4()
- }
- /**
- * DEBUG DATA
- **/
- type Test struct {
- Str string `ini:"String"`
- UnquotedString string
- MultipleLines string
- WithoutValue bool
- Date ini.Date
- Time ini.Time
- TestTime time.Time
- IP ini.IP
- Int struct {
- Int int
- Int8 int8
- Int16 int16
- Int32 int32
- Int64 int64
- Uint struct {
- Uint uint
- Uint8 uint8
- Uint16 uint16
- Uint32 uint32
- Uint64 uint64
- }
- }
- Float struct {
- Float32 float32
- Float64 float64
- }
- }
- func (t *Test) String() string {
- return fmt.Sprintf(`
- STRUCT DATA:
- Str: %v
- UnquotedString: %v
- MultipleLines: %v
- WithoutValue: %v
- Date: %v
- Time: %v
- TestTime: %v
- IP: %v
- Int {
- Int: %v
- Int8: %v
- Int16: %v
- Int32: %v
- Int64: %v
- Uint {
- Uint: %v
- Uint8: %v
- Uint16: %v
- Uint32: %v
- Uint64: %v
- }
- }
- Float {
- Float32: %v
- Float64: %v
- }`,
- t.Str, t.UnquotedString, strings.Replace(t.MultipleLines, "\n", "\n\t\t\t\t", -1), t.WithoutValue, t.Date, t.Time, t.TestTime, t.IP,
- t.Int.Int, t.Int.Int8, t.Int.Int16, t.Int.Int32, t.Int.Int64,
- t.Int.Uint.Uint, t.Int.Uint.Uint8, t.Int.Uint.Uint16, t.Int.Uint.Uint32, t.Int.Uint.Uint64,
- t.Float.Float32, t.Float.Float64,
- )
- }
- func sep(f, e string) {
- var s []byte
- for i := 0; i < 80; i++ {
- s = append(s, '/')
- }
- fmt.Println(f, string(s), e)
- }
- func debug() {
- text := `
- String = "This is some text"
- UnquotedString = This is some unquoted text
- MultipleLines = This is \
- multiple lines \
- going on
- WithoutValue
- Date = 2017-9-28-Local-0
- Time = 01 Jan 01 00:00 UTC
- IP = ::
- [Int]
- Int = -1
- Int8 = -8
- Int16 = -16
- Int32 = -32
- Int64 = -64
- [Int.Uint]
- Uint = 1
- Uint8 = 8
- Uint16 = 16
- Uint32 = 32
- Uint64 = 64
- Uint64 = 64
- [Float]
- Float32 = 3.14722354762387648273648726348
- Float64 = 10.00003423472342734897234872347293748`
- first := &Test{}
- sep("", "")
- fmt.Println(" ### INI TO UNMARSHAL:")
- sep("", "")
- fmt.Println(text)
- sep("\n", "")
- fmt.Println(" ### INITIAL STRUCT VALUES (empty/unset values):")
- sep("", "")
- fmt.Println(first)
- sep("\n", "")
- fmt.Println(" --- NOW MARSHALING: INI -> STRUCT ---")
- err := ini.Unmarshal([]byte(text), first)
- fmt.Println(" !!! ERROR ON UMARSHALING:", err)
- sep("", "")
- fmt.Println(" ### NEW STRUCT VALUES (unmarshaled from INI):")
- sep("", "\n")
- fmt.Println(first)
- sep("\n", "")
- fmt.Println(" --- NOW UNMARSHALING: STRUCT -> INI ---")
- unm, err := ini.Marshal(first)
- fmt.Println(" !!! ERROR ON MARCHALING:", err)
- sep("", "")
- fmt.Println(" ### PRODUCED INI (marshaled from STRUCT)")
- sep("", "")
- fmt.Println(string(unm))
- sep("", "")
- }
|