@@ -30,8 +30,8 @@ const (
3030 _Slice
3131 // We don't use the next two. They are placeholders. See the spec
3232 // for more details.
33- _Container //nolint: deadcode, varcheck // above
34- _Marker //nolint: deadcode, varcheck // above
33+ _Container //nolint:deadcode,varcheck // above
34+ _Marker //nolint:deadcode,varcheck // above
3535 _Bool
3636 _Float32
3737)
@@ -89,6 +89,82 @@ func (d *decoder) decodeToDeserializer(
8989 return d .decodeFromTypeToDeserializer (typeNum , size , newOffset , dser , depth + 1 )
9090}
9191
92+ func (d * decoder ) decodePath (
93+ offset uint ,
94+ path []any ,
95+ result reflect.Value ,
96+ ) error {
97+ PATH:
98+ for i , v := range path {
99+ var (
100+ typeNum dataType
101+ size uint
102+ err error
103+ )
104+ typeNum , size , offset , err = d .decodeCtrlData (offset )
105+ if err != nil {
106+ return err
107+ }
108+
109+ if typeNum == _Pointer {
110+ pointer , _ , err := d .decodePointer (size , offset )
111+ if err != nil {
112+ return err
113+ }
114+
115+ typeNum , size , offset , err = d .decodeCtrlData (pointer )
116+ if err != nil {
117+ return err
118+ }
119+ }
120+
121+ switch v := v .(type ) {
122+ case string :
123+ // We are expecting a map
124+ if typeNum != _Map {
125+ // XXX - use type names in errors.
126+ return fmt .Errorf ("expected a map for %s but found %d" , v , typeNum )
127+ }
128+ for i := uint (0 ); i < size ; i ++ {
129+ var key []byte
130+ key , offset , err = d .decodeKey (offset )
131+ if err != nil {
132+ return err
133+ }
134+ if string (key ) == v {
135+ continue PATH
136+ }
137+ offset , err = d .nextValueOffset (offset , 1 )
138+ if err != nil {
139+ return err
140+ }
141+ }
142+ // Not found. Maybe return a boolean?
143+ return nil
144+ case int :
145+ // We are expecting an array
146+ if typeNum != _Slice {
147+ // XXX - use type names in errors.
148+ return fmt .Errorf ("expected a slice for %d but found %d" , v , typeNum )
149+ }
150+ if size < uint (v ) {
151+ // Slice is smaller than index, not found
152+ return nil
153+ }
154+ // TODO: support negative indexes? Seems useful for subdivisions in
155+ // particular.
156+ offset , err = d .nextValueOffset (offset , uint (v ))
157+ if err != nil {
158+ return err
159+ }
160+ default :
161+ return fmt .Errorf ("unexpected type for %d value in path, %v: %T" , i , v , v )
162+ }
163+ }
164+ _ , err := d .decode (offset , result , len (path ))
165+ return err
166+ }
167+
92168func (d * decoder ) decodeCtrlData (offset uint ) (dataType , uint , uint , error ) {
93169 newOffset := offset + 1
94170 if offset >= uint (len (d .buffer )) {
0 commit comments