hasJSONRPCIDFieldRec walks the attribute graph looking for the jsonrpc:id meta while guarding against cycles that may occur with recursive user types.
(attr *AttributeExpr, seen map[*AttributeExpr]struct{}, seenUT map[string]struct{})
| 1192 | // hasJSONRPCIDFieldRec walks the attribute graph looking for the jsonrpc:id meta |
| 1193 | // while guarding against cycles that may occur with recursive user types. |
| 1194 | func hasJSONRPCIDFieldRec(attr *AttributeExpr, seen map[*AttributeExpr]struct{}, seenUT map[string]struct{}) bool { |
| 1195 | if attr == nil || attr.Type == Empty { |
| 1196 | return false |
| 1197 | } |
| 1198 | if _, ok := seen[attr]; ok { |
| 1199 | return false |
| 1200 | } |
| 1201 | seen[attr] = struct{}{} |
| 1202 | |
| 1203 | // Check if this attribute itself has the jsonrpc:id meta tag |
| 1204 | if attr.Meta != nil { |
| 1205 | if _, hasID := attr.Meta["jsonrpc:id"]; hasID { |
| 1206 | return true |
| 1207 | } |
| 1208 | } |
| 1209 | |
| 1210 | // For object types, check all nested attributes |
| 1211 | if obj := AsObject(attr.Type); obj != nil { |
| 1212 | for _, nat := range *obj { |
| 1213 | if hasJSONRPCIDFieldRec(nat.Attribute, seen, seenUT) { |
| 1214 | return true |
| 1215 | } |
| 1216 | } |
| 1217 | } |
| 1218 | |
| 1219 | // For user types, check the underlying attribute (guarding for recursion) |
| 1220 | if ut, ok := attr.Type.(UserType); ok { |
| 1221 | if ut != nil { |
| 1222 | if _, ok := seenUT[ut.ID()]; ok { |
| 1223 | return false |
| 1224 | } |
| 1225 | seenUT[ut.ID()] = struct{}{} |
| 1226 | return hasJSONRPCIDFieldRec(ut.Attribute(), seen, seenUT) |
| 1227 | } |
| 1228 | } |
| 1229 | return false |
| 1230 | } |
no test coverage detected