dati

data and template interface
git clone git://git.gearsix.net/dati
Log | Files | Refs | Atom | README | LICENSE

data.go (2510B)


      1 package dati
      2 
      3 /*
      4 Copyright (C) 2021 gearsix <gearsix@tuta.io>
      5 
      6 This program is free software: you can redistribute it and/or modify
      7 it under the terms of the GNU General Public License as published by
      8 the Free Software Foundation, either version 3 of the License, or
      9 at your option) any later version.
     10 
     11 This program is distributed in the hope that it will be useful,
     12 but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 GNU General Public License for more details.
     15 
     16 You should have received a copy of the GNU General Public License
     17 along with this program.  If not, see <https://www.gnu.org/licenses/>.
     18 */
     19 
     20 import (
     21 	"encoding/json"
     22 	"fmt"
     23 	"github.com/pelletier/go-toml"
     24 	"gopkg.in/yaml.v3"
     25 	"io"
     26 	"io/ioutil"
     27 	"os"
     28 	"path/filepath"
     29 	"strings"
     30 )
     31 
     32 // SupportedDataLangs provides a list of supported languages for data files (lower-case)
     33 var SupportedDataLangs = []string{"json", "yaml", "toml"}
     34 
     35 // IsSupportedDataLang provides the index of `SupportedLangs` that `lang` is at.
     36 // If `lang` is not in `SupportedDataLangs`, `-1` will be returned.
     37 // File extensions can be passed in `lang`, the prefixed `.` will be trimmed.
     38 func IsSupportedDataLang(lang string) int {
     39 	lang = strings.ToLower(lang)
     40 	if len(lang) > 0 && lang[0] == '.' {
     41 		lang = lang[1:]
     42 	}
     43 	for i, l := range SupportedDataLangs {
     44 		if lang == l {
     45 			return i
     46 		}
     47 	}
     48 	return -1
     49 }
     50 
     51 // LoadData attempts to load all data from `in` as the data language `lang`
     52 // and writes the result in the pointer `outp`.
     53 func LoadData(lang string, in io.Reader, outp interface{}) error {
     54 	inbuf, e := ioutil.ReadAll(in)
     55 	if e != nil {
     56 		return e
     57 	} else if len(inbuf) == 0 {
     58 		return nil
     59 	}
     60 
     61 	switch IsSupportedDataLang(lang) {
     62 	case 0:
     63 		e = json.Unmarshal(inbuf, outp)
     64 	case 1:
     65 		e = yaml.Unmarshal(inbuf, outp)
     66 	case 2:
     67 		e = toml.Unmarshal(inbuf, outp)
     68 	case -1:
     69 		fallthrough
     70 	default:
     71 		e = fmt.Errorf("'%s' is not a supported data language", lang)
     72 	}
     73 
     74 	return e
     75 }
     76 
     77 // LoadDataFile loads all the data from the file found at `path` into the the
     78 // format of that files extension (e.g. "x.json" will be loaded as a json).
     79 // The result is written to the value pointed at by `outp`.
     80 func LoadDataFilepath(path string, outp interface{}) error {
     81 	f, e := os.Open(path)
     82 	defer f.Close()
     83 
     84 	if e == nil {
     85 		lang := filepath.Ext(path)[1:] // don't include '.'
     86 		if e = LoadData(lang, f, outp); e != nil {
     87 			e = fmt.Errorf("failed to load data '%s': %s", path, e.Error())
     88 		}
     89 	}
     90 
     91 	return e
     92 }