github.com/zignig/go-ipfs@v0.0.0-20141111235910-c9e5fdf55a52/config/serialize.go (about) 1 package config 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "os" 8 "path/filepath" 9 "strings" 10 ) 11 12 // ReadConfigFile reads the config from `filename` into `cfg`. 13 func ReadConfigFile(filename string, cfg interface{}) error { 14 f, err := os.Open(filename) 15 if err != nil { 16 return err 17 } 18 defer f.Close() 19 20 return Decode(f, cfg) 21 } 22 23 // WriteConfigFile writes the config from `cfg` into `filename`. 24 func WriteConfigFile(filename string, cfg interface{}) error { 25 err := os.MkdirAll(filepath.Dir(filename), 0775) 26 if err != nil { 27 return err 28 } 29 30 f, err := os.Create(filename) 31 if err != nil { 32 return err 33 } 34 defer f.Close() 35 36 return Encode(f, cfg) 37 } 38 39 // WriteFile writes the buffer at filename 40 func WriteFile(filename string, buf []byte) error { 41 err := os.MkdirAll(filepath.Dir(filename), 0775) 42 if err != nil { 43 return err 44 } 45 46 f, err := os.Create(filename) 47 if err != nil { 48 return err 49 } 50 defer f.Close() 51 52 _, err = f.Write(buf) 53 return err 54 } 55 56 // Encode configuration with JSON 57 func Encode(w io.Writer, value interface{}) error { 58 // need to prettyprint, hence MarshalIndent, instead of Encoder 59 buf, err := json.MarshalIndent(value, "", " ") 60 if err != nil { 61 return err 62 } 63 64 _, err = w.Write(buf) 65 return err 66 } 67 68 // Decode configuration with JSON 69 func Decode(r io.Reader, value interface{}) error { 70 return json.NewDecoder(r).Decode(value) 71 } 72 73 // ReadConfigKey retrieves only the value of a particular key 74 func ReadConfigKey(filename, key string) (interface{}, error) { 75 var cfg interface{} 76 if err := ReadConfigFile(filename, &cfg); err != nil { 77 return nil, err 78 } 79 80 var ok bool 81 cursor := cfg 82 parts := strings.Split(key, ".") 83 for i, part := range parts { 84 cursor, ok = cursor.(map[string]interface{})[part] 85 if !ok { 86 sofar := strings.Join(parts[:i], ".") 87 return nil, fmt.Errorf("%s key has no attributes", sofar) 88 } 89 } 90 return cursor, nil 91 } 92 93 // WriteConfigKey writes the value of a particular key 94 func WriteConfigKey(filename, key string, value interface{}) error { 95 var cfg interface{} 96 if err := ReadConfigFile(filename, &cfg); err != nil { 97 return err 98 } 99 100 var ok bool 101 var mcursor map[string]interface{} 102 cursor := cfg 103 104 parts := strings.Split(key, ".") 105 for i, part := range parts { 106 mcursor, ok = cursor.(map[string]interface{}) 107 if !ok { 108 sofar := strings.Join(parts[:i], ".") 109 return fmt.Errorf("%s key is not a map", sofar) 110 } 111 112 // last part? set here 113 if i == (len(parts) - 1) { 114 mcursor[part] = value 115 break 116 } 117 118 cursor, ok = mcursor[part] 119 if !ok { // create map if this is empty 120 mcursor[part] = map[string]interface{}{} 121 cursor = mcursor[part] 122 } 123 } 124 125 return WriteConfigFile(filename, cfg) 126 }