form icon indicating copy to clipboard operation
form copied to clipboard

Add field name normalization

Open ivanjaros opened this issue 1 year ago • 1 comments

Package version eg. v9, v10:

v4

Issue, Question or Enhancement:

The url query can have fields like foo[bar]=baz, foo[0]=baz, foo[0]bar[0]baz=car and so on. The thing is that foo[0] and foo[bar] are distinctively different types - obviously a map/struct and array/slice. Because this library requires dot as delimiter, I have to replace foo[bar] with foo.bar otherwise it will not work for nested structs. I can use simple replacer strings.NewReplacer("][", ".", "[", ".", "]", "") but the problem is that it will screw up arrays by changing foo[0] into foo.0 which is incorrect. So it would be nice to have a built-in function that handles this appropriately and returns altered map(url query) or directly consumes values and handles the key massaging internally.

ivanjaros avatar Oct 16 '24 19:10 ivanjaros

Maybe something like:

func keyParser(src string) string {
	runes := []rune(src)
PARSE_LOOP:
	for k, v := range runes {
		if v != '[' {
			continue
		}
		// we are on the last entry, which means this is invalid string, like "foo[0][" or "foo["
		if len(runes)-k <= 1 {
			continue
		}
		// skip arrays(foo[0..9])
		if runes[k+1] >= '0' && runes[k+1] <= '9' {
			continue
		}
		// replace the bracket with object path separator(dot)
		runes[k] = '.'
		// find the closing bracket and remove it
		for i := k + 1; i < len(runes); i++ {
			if runes[i] == ']' {
				runes = append(runes[:i], runes[i+1:]...)
				goto PARSE_LOOP
			}
		}
	}
	return string(runes)
}

ivanjaros avatar Oct 17 '24 08:10 ivanjaros