beardface / gcfg

Automatically exported from code.google.com/p/gcfg
Other
0 stars 0 forks source link

sections with user-supplied variable names #8

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
gcfg should support sections with all user-supplied variable names.
An equivalent example in gitconfig would be the [alias] section.

Original issue reported on code.google.com by speter....@gmail.com on 11 May 2014 at 2:47

GoogleCodeExporter commented 9 years ago
does it really need to be more complex than a map[string]string ?

Original comment by am...@geeks.cl on 29 May 2014 at 12:20

GoogleCodeExporter commented 9 years ago
The reason I want to avoid using map[string]string comes from two factors. The 
first is the preference for ease of use for users (those editing the config 
files) over ease of use for developers. The second is the preference for APIs 
that are easier to use correctly than incorrectly.

The first means that variable names should remain case-insensitive (as in other 
sections, and as in git config). This provides simplicity for users by reducing 
the things they need to pay attention to when editing the files. (Other 
formats/packages such as json may be better suited if/when ease of use for the 
developer is preferred over ease of editing.)

Based on this, using a map with a string key would make it very easy for 
developers to incorrectly look up elements by the key in a case-sensitive 
manner. This in turn creates inconsistency with other sections in the same 
file, as well as with other programs using the gcfg format/package.

An additional but relatively minor issue with map[string]string is the value 
type -- gcfg aims to support arbitrary types in a type-safe manner. (Even 
though the first priority is ease of use for users, gcfg still does aim to do 
as much as possible to assist the developer as well.) This itself (ignoring the 
aforementioned issues for a second) could be solved by just using map[string]T 
(as long as it can be distinguished from a subsection map definition), but it 
complicates API design when trying to provide case-insensitive lookup with 
user-defined value types.

I have a rough idea of an API that could enforce (or at least strongly 
encourage) case-insensitive usage; using an opaque interim type gcfg.Idx for 
keys, and having the developer embed an extra field that provides the methods 
for lookup (and holds any additional data needed for lookup):

var cfg = &struct {
    Alias struct {
        gcfg.Idxer
        Vals map[gcfg.Idx]MyType
    }
}{}

var cfgStr = `
[alias]
lg=log`

func ExampleIdxer() {
    if err := gcfg.ReadStringInto(cfg, cfgStr); err != nil {
        panic(err)
    }
    alias := &cfg.Alias
    // Idx(string): look up variable with known name (case-insensitive)
    if val, ok := alias.Vals[alias.Idx("LG")]; ok {
        fmt.Println(val)
    }
    // Names(): iterate over variables with undefined order and case
    for _, n := range alias.Names() {
        fmt.Println(n, alias.Vals[alias.Idx(n)])
    }
}

Suggestions for enhancements or alternative approaches are welcome.

Original comment by speter....@gmail.com on 1 Jun 2014 at 1:29

GoogleCodeExporter commented 9 years ago
sounds good to me. :) but I have no clue how to implent `gcfg.Idxer` ... do you 
have a branch somewhere to test?

Original comment by am...@geeks.cl on 15 Jun 2014 at 1:14

GoogleCodeExporter commented 9 years ago
This issue was updated by revision 1390defd5d3d.

Original comment by speter....@gmail.com on 4 Jul 2014 at 10:21