github.com/go-kivik/kivik/v4@v4.3.2/x/fsdb/cdb/decode/decode.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 12 13 // Package decode assists in document decoding. 14 package decode 15 16 import ( 17 "fmt" 18 "io" 19 "os" 20 "path/filepath" 21 "sort" 22 "strings" 23 24 "github.com/go-kivik/kivik/v4/x/fsdb/filesystem" 25 ) 26 27 type decoder interface { 28 Decode(io.Reader, interface{}) error 29 } 30 31 var decoders = map[string]decoder{ 32 "json": &jsonDecoder{}, 33 "yaml": &yamlDecoder{}, 34 "yml": &yamlDecoder{}, 35 } 36 37 var extensions = func() []string { 38 exts := make([]string, 0, len(decoders)) 39 for ext := range decoders { 40 exts = append(exts, ext) 41 } 42 sort.Strings(exts) 43 return exts 44 }() 45 46 // OpenAny attempts to open base + any supported extension. It returns the open 47 // file, the matched extension, or an error. 48 func OpenAny(fs filesystem.Filesystem, base string) (f filesystem.File, ext string, err error) { 49 for ext = range decoders { 50 f, err = fs.Open(base + "." + ext) 51 if err == nil || !os.IsNotExist(err) { 52 return 53 } 54 } 55 return 56 } 57 58 // Decode decodes r according to ext's registered decoder, into i. 59 func Decode(r io.Reader, ext string, i interface{}) error { 60 ext = strings.TrimPrefix(ext, ".") 61 dec, ok := decoders[ext] 62 if !ok { 63 return fmt.Errorf("No decoder for %s", ext) 64 } 65 return dec.Decode(r, i) 66 } 67 68 // ExplodeFilename returns the base name, extension, and a boolean indicating 69 // whether the extension is decodable. 70 func ExplodeFilename(filename string) (basename, ext string, ok bool) { 71 dotExt := filepath.Ext(filename) 72 basename = strings.TrimSuffix(filename, dotExt) 73 ext = strings.TrimPrefix(dotExt, ".") 74 _, ok = decoders[ext] 75 return basename, ext, ok 76 } 77 78 // Extensions returns a list of supported extensions. 79 func Extensions() []string { 80 return extensions 81 }