<commit_before>package libkb

import (
	"github.com/keybase/go-jsonw"
)

type JsonConfigFile struct {
	JsonFile
}

type JsonConfigAdjuster struct {
	file *JsonConfigFile
}

func NewJsonConfigFile(s string) *JsonConfigFile {
	return &JsonConfigFile{*NewJsonFile(s, "config")}
}

func NewJsonConfigAdjuster(f *JsonConfigFile) *JsonConfigAdjuster {
	return &JsonConfigAdjuster{f}
}

type valueGetter func(*jsonw.Wrapper) (interface{}, error)

func (f JsonConfigFile) getValueAtPath(
	p string, getter valueGetter) (ret interface{}, is_set bool) {
	is_set = false
	if f.jw != nil {
		var err error
		ret, err = getter(f.jw.AtPath(p))
		if err == nil {
			is_set = true
		}
	}
	return
}

func getString(w *jsonw.Wrapper) (interface{}, error) {
	return w.GetString()
}

func getBool(w *jsonw.Wrapper) (interface{}, error) {
	return w.GetBool()
}

func getInt(w *jsonw.Wrapper) (interface{}, error) {
	return w.GetInt()
}

func (f JsonConfigFile) GetStringAtPath(p string) (ret string, is_set bool) {
	i, is_set := f.getValueAtPath(p, getString)
	ret = i.(string)
	return
}

func (f JsonConfigFile) GetBoolAtPath(p string) (ret bool, is_set bool) {
	i, is_set := f.getValueAtPath(p, getBool)
	ret = i.(bool)
	return
}

func (f JsonConfigFile) GetIntAtPath(p string) (ret int, is_set bool) {
	i, is_set := f.getValueAtPath(p, getInt)
	ret = i.(int)
	return
}

func (f JsonConfigFile) GetNullAtPath(p string) (is_set bool) {
	is_set = false
	if f.jw != nil {
		w := f.jw.AtPath(p)
		is_set = w.IsNil() && w.Error() == nil
	}
	return
}

func (f JsonConfigFile) GetTopLevelString(s string) (ret string) {
	var e error
	if f.jw != nil {
		f.jw.AtKey(s).GetStringVoid(&ret, &e)
		G.Log.Debug("Config: mapping %s -> %s", s, ret)
	}
	return
}

func (f JsonConfigFile) GetTopLevelBool(s string) (res bool, is_set bool) {
	is_set = false
	res = false
	if f.jw != nil {
		if w := f.jw.AtKey(s); !w.IsNil() {
			is_set = true
			var e error
			w.GetBoolVoid(&res, &e)
		}
	}
	return
}

func (f *JsonConfigFile) UserDict() *jsonw.Wrapper {
	if f.jw == nil {
		f.jw = jsonw.NewDictionary()
	}
	if f.jw.AtKey("user").IsNil() {
		f.jw.SetKey("user", jsonw.NewDictionary())
	}
	return f.jw.AtKey("user")
}

func (f *JsonConfigFile) setValueAtPath(
	p string, getter valueGetter, v interface{}) (err error) {
	existing, err := getter(f.jw.AtPath(p))

	if err != nil || existing != v {
		err = f.jw.SetValueAtPath(p, jsonw.NewWrapper(v))
		if err == nil {
			f.dirty = true
		}
	}
	return
}

func (f *JsonConfigFile) SetStringAtPath(p string, v string) (err error) {
	return f.setValueAtPath(p, getString, v)
}

func (f *JsonConfigFile) SetBoolAtPath(p string, v bool) (err error) {
	return f.setValueAtPath(p, getBool, v)
}

func (f *JsonConfigFile) SetIntAtPath(p string, v int) (err error) {
	return f.setValueAtPath(p, getInt, v)
}

func (f *JsonConfigFile) SetNullAtPath(p string) (err error) {
	existing := f.jw.AtPath(p)

	if !existing.IsNil() || existing.Error() != nil {
		err = f.jw.SetValueAtPath(p, jsonw.NewNil())
		if err == nil {
			f.dirty = true
		}
	}
	return
}

func (f *JsonConfigFile) SetUsername(s string) {
	f.SetUserField("name", s)
}

func (f *JsonConfigFile) SetUid(s string) {
	f.SetUserField("id", s)
}

func (f *JsonConfigFile) SetSalt(s string) {
	f.SetUserField("salt", s)
}
<commit_msg>a few more related bugfixes<commit_after>package libkb

import (
	"github.com/keybase/go-jsonw"
)

type JsonConfigFile struct {
	JsonFile
}

type JsonConfigAdjuster struct {
	file *JsonConfigFile
}

func NewJsonConfigFile(s string) *JsonConfigFile {
	return &JsonConfigFile{*NewJsonFile(s, "config")}
}

func NewJsonConfigAdjuster(f *JsonConfigFile) *JsonConfigAdjuster {
	return &JsonConfigAdjuster{f}
}

type valueGetter func(*jsonw.Wrapper) (interface{}, error)

func (f JsonConfigFile) getValueAtPath(
	p string, getter valueGetter) (ret interface{}, is_set bool) {
	is_set = false
	if f.jw != nil {
		var err error
		ret, err = getter(f.jw.AtPath(p))
		if err == nil {
			is_set = true
		}
	}
	return
}

func getString(w *jsonw.Wrapper) (interface{}, error) {
	return w.GetString()
}

func getBool(w *jsonw.Wrapper) (interface{}, error) {
	return w.GetBool()
}

func getInt(w *jsonw.Wrapper) (interface{}, error) {
	return w.GetInt()
}

func (f JsonConfigFile) GetStringAtPath(p string) (ret string, is_set bool) {
	i, is_set := f.getValueAtPath(p, getString)
	ret = i.(string)
	return
}

func (f JsonConfigFile) GetBoolAtPath(p string) (ret bool, is_set bool) {
	i, is_set := f.getValueAtPath(p, getBool)
	ret = i.(bool)
	return
}

func (f JsonConfigFile) GetIntAtPath(p string) (ret int, is_set bool) {
	i, is_set := f.getValueAtPath(p, getInt)
	ret = i.(int)
	return
}

func (f JsonConfigFile) GetNullAtPath(p string) (is_set bool) {
	is_set = false
	if f.jw != nil {
		w := f.jw.AtPath(p)
		is_set = w.IsNil() && w.Error() == nil
	}
	return
}

func (f JsonConfigFile) GetTopLevelString(s string) (ret string) {
	var e error
	if f.jw != nil {
		f.jw.AtKey(s).GetStringVoid(&ret, &e)
		G.Log.Debug("Config: mapping %s -> %s", s, ret)
	}
	return
}

func (f JsonConfigFile) GetTopLevelBool(s string) (res bool, is_set bool) {
	is_set = false
	res = false
	if f.jw != nil {
		if w := f.jw.AtKey(s); !w.IsNil() {
			is_set = true
			var e error
			w.GetBoolVoid(&res, &e)
		}
	}
	return
}

func (f *JsonConfigFile) UserDict() *jsonw.Wrapper {
	f.CheckOrCreateJsonObj()
	if f.jw.AtKey("user").IsNil() {
		f.jw.SetKey("user", jsonw.NewDictionary())
		f.dirty = true
	}
	return f.jw.AtKey("user")
}

func (f *JsonConfigFile) setValueAtPath(
	p string, getter valueGetter, v interface{}) (err error) {
	existing, err := getter(f.jw.AtPath(p))

	if err != nil || existing != v {
		err = f.jw.SetValueAtPath(p, jsonw.NewWrapper(v))
		if err == nil {
			f.dirty = true
		}
	}
	return
}

func (f *JsonConfigFile) SetStringAtPath(p string, v string) (err error) {
	return f.setValueAtPath(p, getString, v)
}

func (f *JsonConfigFile) SetBoolAtPath(p string, v bool) (err error) {
	return f.setValueAtPath(p, getBool, v)
}

func (f *JsonConfigFile) SetIntAtPath(p string, v int) (err error) {
	return f.setValueAtPath(p, getInt, v)
}

func (f *JsonConfigFile) CheckOrCreateJsonObj() {
	if f.jw == nil {
		f.Reset()
	}
}

func (f *JsonConfigFile) SetNullAtPath(p string) (err error) {
	f.CheckOrCreateJsonObj()
	existing := f.jw.AtPath(p)
	if !existing.IsNil() || existing.Error() != nil {
		err = f.jw.SetValueAtPath(p, jsonw.NewNil())
		if err == nil {
			f.dirty = true
		}
	}
	return
}

func (f *JsonConfigFile) SetUsername(s string) {
	f.SetUserField("name", s)
}

func (f *JsonConfigFile) SetUid(s string) {
	f.SetUserField("id", s)
}

func (f *JsonConfigFile) SetSalt(s string) {
	f.SetUserField("salt", s)
}

{'fraction_non_alphanumeric': 0.1517910447761194, 'fraction_numerical': 0.0, 'mean_word_length': 4.146697388632872, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4275598', 'n_tokens_mistral': 2776, 'n_tokens_neox': 2719, 'n_words': 661}