Search Apps Documentation Source Content File Folder Download Copy Actions Download

property_parser.gno

1.39 Kb · 59 lines
 1package personal_world
 2
 3import "net/url"
 4
 5// parsePropertiesCSV accepts comma-separated keys and comma-separated values.
 6// Each value must be URL-encoded so commas and other separators can be carried
 7// safely; this parser URL-decodes values before returning the map.
 8//
 9// Empty key lists and empty keys are rejected because keys define the map
10// shape. Empty values are policy-dependent, so the parser preserves them for
11// the create/update validator.
12func parsePropertiesCSV(keys, values string) map[string]string {
13	if keys == "" {
14		panic("properties keys must be not empty")
15	}
16
17	result := map[string]string{}
18	keyStart, valStart := 0, 0
19	keyIdx, valIdx := 0, 0
20
21	for {
22		for keyIdx < len(keys) && keys[keyIdx] != ',' {
23			keyIdx++
24		}
25		for valIdx < len(values) && values[valIdx] != ',' {
26			valIdx++
27		}
28
29		key := keys[keyStart:keyIdx]
30		if key == "" {
31			panic("properties key must be not empty")
32		}
33		if _, found := result[key]; found {
34			panic("properties key duplicated: " + key)
35		}
36
37		value, err := url.PathUnescape(values[valStart:valIdx])
38		if err != nil {
39			panic("properties value URL decode failed: " + key)
40		}
41		result[key] = value
42
43		keyEnd := keyIdx >= len(keys)
44		valEnd := valIdx >= len(values)
45		if keyEnd != valEnd {
46			panic("properties keys and values count mismatch")
47		}
48		if keyEnd {
49			break
50		}
51
52		keyIdx++
53		valIdx++
54		keyStart = keyIdx
55		valStart = valIdx
56	}
57
58	return result
59}