func NewConfigFrom()

in loader/config.go [65:139]


func NewConfigFrom(from interface{}, opts ...interface{}) (*Config, error) {
	if len(opts) == 0 {
		opts = DefaultOptions
	}
	var ucfgOpts []ucfg.Option
	var localOpts []Option
	for _, o := range opts {
		switch ot := o.(type) {
		case ucfg.Option:
			ucfgOpts = append(ucfgOpts, ot)
		case Option:
			localOpts = append(localOpts, ot)
		default:
			return nil, fmt.Errorf("unknown option type %T", o)
		}
	}
	local := &options{}
	for _, o := range localOpts {
		o(local)
	}

	var data map[string]interface{}
	var err error
	if bytes, ok := from.([]byte); ok {
		err = yaml.Unmarshal(bytes, &data)
		if err != nil {
			return nil, err
		}
	} else if str, ok := from.(string); ok {
		err = yaml.Unmarshal([]byte(str), &data)
		if err != nil {
			return nil, err
		}
	} else if in, ok := from.(io.Reader); ok {
		if closer, ok := from.(io.Closer); ok {
			defer closer.Close()
		}
		fData, err := io.ReadAll(in)
		if err != nil {
			return nil, err
		}
		err = yaml.Unmarshal(fData, &data)
		if err != nil {
			return nil, err
		}
	} else if contents, ok := from.(map[string]interface{}); ok {
		data = contents
	} else {
		c, err := ucfg.NewFrom(from, ucfgOpts...)
		return newConfigFrom(c), err
	}

	skippedKeys := map[string]interface{}{}
	for _, skip := range local.skipKeys {
		val, ok := data[skip]
		if ok {
			skippedKeys[skip] = val
			delete(data, skip)
		}
	}
	cfg, err := ucfg.NewFrom(data, ucfgOpts...)
	if err != nil {
		return nil, err
	}
	if len(skippedKeys) > 0 {
		err = cfg.Merge(skippedKeys, ucfg.ResolveNOOP)

		// we modified incoming object
		// cleanup so skipped keys are not missing
		for k, v := range skippedKeys {
			data[k] = v
		}
	}
	return newConfigFrom(cfg), err
}