internal: update structpath to accept both dot and bracket syntax for fields and maps#3640
Merged
internal: update structpath to accept both dot and bracket syntax for fields and maps#3640
Conversation
This was referenced Sep 22, 2025
Collaborator
9 failing tests:
|
Previously structpath could represent AnyKey and AnyIndex as struct but as string they were both represented as field[*]. On the other hand, there was no unambigous representation of x.*. This commit fixes struct mapping to match string representation 1-1 so that Parse(x.String()) == x.
57285ac to
e627b0e
Compare
andrewnester
approved these changes
Sep 24, 2025
github-merge-queue bot
pushed a commit
that referenced
this pull request
Dec 2, 2025
…ys (#4041) ## Changes - Update structpath to distinguish between fields (.field) and map keys (["field"]). Note, when it comes to references, we still accept any syntax. However, structdiff and structwalk accurately represent map keys now. - Update server_side_default logic to ignore map keys. ## Why It was never the intention for map entries to have "server_side_default" feature. (Similar to slice indices in #4038). Issue appeared when we stopped distinguishing between fields and map keys in struct path #3640 Note, originally the difference between fields and map keys was removed so that a) users can use either syntax without worrying about matching the type. This is still the case, structaccess still treats those two the same way. b) "resources.jobs.foo" is printed with dots and not like 'resources.jobs["foo"]'. This is still the case, we don't use structpath's String() for this. ## Tests New regression test.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
Simplify internal representation of structpath.PathNode: struct fields and map keys are represented the same way internally.
When parsing, users can specify either
.fieldor[‘field’], both will be encoded as tagStringKey in PathNode.When saving PathNode as string, String() selects appropriate encoding (prefers dot unless it uses reserved characters). DynPath() is removed, String() returns DynPath()-like value for those values that can be represented by dot notation.
At the same time, PathNode now accurately represents
foo.*vsfoo[*], this structure is preserved and not equivalent. This again improves compatibility with dyn.Path as it represents index and keys wildcard differently.structaccess is updated to accept PathNode. Since PathNode only gives StringKey() now and does not distinguish between map and struct fields, structaccess.Get essentially supports both syntaxes for both kinds.
structwalk is updated to emit dotStar for map wildcards, making it compatible with code expecting dyn.Pattern (this is used for required fields and enum validation).
structwalk.PathNode.String() is rewritten to be iterative rather than recursive.
PathNode gets new methods: Prefix(N), SkipPrefix(N), AsSlice().
Why
Dot notation is currently used for maps e.g. "resources.jobs.foo". With precise map encoding that would look like "resources.jobs['foo']" which looks unfamiliar and also will not match if someone does string comparison against "resources.jobs.foo".
Adopting this scheme makes it easier to work with PathNode in dyn.Path world and in fact makes it drop-in replacement (the syntax is superset).
Tests
Existing and new unit tests.