<commit_before>package bconf

import (
	"encoding/json"
	"sort"
)

type Bconf map[string]interface{}

type sortednode []struct {
	k string
	v interface{}
}

func (bc *Bconf)LoadJson(js []byte) error {
	err := json.Unmarshal(js, bc)

	if bc != nil && len(*bc) > 0 {
		*bc = normalize(*bc)
	}

	return err
}

/*
 * Normalize what we read from json by changing the data types from
 * map[string]interface{} into Bconf
 */
func normalize(bc Bconf) Bconf {
	nb := make(Bconf)
	for k, v := range(bc) {
		var nv interface{}
		switch (v.(type)) {
		case map[string]interface{}:
			nv = normalize(Bconf(v.(map[string]interface{})))
		default:
			nv = v
		}
		nb[k] = nv
	}
	return nb
}

func (bc Bconf) get(k ...string) interface{} {
	if len(k) == 0 {
		return bc
	}

	n := bc[k[0]]

	if len(k) == 1 {
		return n
	}

	switch (n.(type)) {
	case Bconf:
		return n.(Bconf).get(k[1:]...)
	}

	return nil
}

func (bc Bconf)GetNode(k ...string) Bconf {
	n := bc.get(k...)
	return Bconf(n.(Bconf))
}

func (bc Bconf)GetString(k ...string) string {
	if len(k) == 0 {
		return ""
	}
	n := bc[k[0]]
	switch (n.(type)) {
	case string:
		if len(k) == 1 {
			return n.(string)
		}
		return ""
	default:
		return n.(Bconf).GetString(k[1:]...)
	}
	return ""
}

func (bc Bconf)ForeachVal(f func(k,v string)) {
	for k, v := range(bc) {
		switch(v.(type)) {
		case string:
			f(k, v.(string))
		}<commit_msg>Fail in GetNode if we didn't find a node instead of doing a brutal cast that might fail.<commit_after>package bconf

import (
	"encoding/json"
	"sort"
)

type Bconf map[string]interface{}

type sortednode []struct {
	k string
	v interface{}
}

func (bc *Bconf)LoadJson(js []byte) error {
	err := json.Unmarshal(js, bc)

	if bc != nil && len(*bc) > 0 {
		*bc = normalize(*bc)
	}

	return err
}

/*
 * Normalize what we read from json by changing the data types from
 * map[string]interface{} into Bconf
 */
func normalize(bc Bconf) Bconf {
	nb := make(Bconf)
	for k, v := range(bc) {
		var nv interface{}
		switch (v.(type)) {
		case map[string]interface{}:
			nv = normalize(Bconf(v.(map[string]interface{})))
		default:
			nv = v
		}
		nb[k] = nv
	}
	return nb
}

func (bc Bconf) get(k ...string) interface{} {
	if len(k) == 0 {
		return bc
	}

	n := bc[k[0]]

	if len(k) == 1 {
		return n
	}

	switch (n.(type)) {
	case Bconf:
		return n.(Bconf).get(k[1:]...)
	}

	return nil
}

func (bc Bconf)GetNode(k ...string) Bconf {
	n := bc.get(k...)
	switch (n.(type)) {
	case Bconf:
		return n
	}
	return nil
}

func (bc Bconf)GetString(k ...string) string {
	if len(k) == 0 {
		return ""
	}
	n := bc[k[0]]
	switch (n.(type)) {
	case string:
		if len(k) == 1 {
			return n.(string)
		}
		return ""
	default:
		return n.(Bconf).GetString(k[1:]...)
	}
	return ""
}

func (bc Bconf)ForeachVal(f func(k,v string)) {
	for k, v := range(bc) {
		switch(v.(type)) {
		case string:
			f(k, v.(string))
		}
{'fraction_non_alphanumeric': 0.18419220055710306, 'fraction_numerical': 0.006267409470752089, 'mean_word_length': 3.0351123595505616, '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': '5570737', 'n_tokens_mistral': 1257, 'n_tokens_neox': 1171, 'n_words': 317}