Closed adamroyjones closed 1 year ago
(I'm sorry for the noise above and below—I made some mistakes which I've tried to tidy away.)
TypeNone
is returned when an object or array ends at the current level.So when you get TypeNone
, the array ends and you must continue parsing the object. When using bare recursive iterators you will need to keep track of your parse depth.
I added an @
where a TypeNone
will be returned: {"foo": ["bar"]@, "baz": {"qux": "bah"}@}@@
Or better, use Object().ForEach
and Array()
to parse arrays and objects.
Here is a simple fix:
func censor(in string) (string, error) {
pj, err := simdjson.Parse([]byte(in), nil)
if err != nil {
return "", err
}
root := pj.Iter()
iter := root
var depth int
TAPELOOP:
for {
switch iter.AdvanceInto().Type() {
case simdjson.TypeNone:
if depth == 0 {
break TAPELOOP
}
depth--
case simdjson.TypeArray, simdjson.TypeObject:
depth++
case simdjson.TypeString:
val, err := iter.String()
if err != nil {
return "", err
}
if val[0] == 'a' {
iter.SetString("x")
}
default:
continue
}
}
ret, err := root.MarshalJSON()
if err != nil {
return "", err
}
return string(ret), nil
}
@adamroyjones Using bare iterators is not easy. That is why there are abstractions for handling objects and arrays.
When using "AdvanceInto" you are basically traversing as it is literally written in the JSON.
This is probably user error, but I'm bumping into issues with the following code of mine. (I'll describe the issues at the bottom.)
Running the tests above leads to:
The intention with the example code is to walk the JSON and censor any matching strings it finds. The issues are twofold.
This may well be user error in both cases—does anyone have any ideas?