Repository navigation
Add MarshalINI and UnmarshalINI for custom key values - #427
Merged
Merged
Conversation
unknwon
force-pushed
the
v2-marshal-ini
branch
2 times, most recently
from
November 10, 2026 21:21
6b8170d to
f3f52e5
Compare
unknwon
force-pushed
the
v2-marshal-ini
branch
3 times, most recently
from
November 11, 2026 03:37
d9cbca5 to
f41421d
Compare
A type with MarshalINI or UnmarshalINI formats or parses its own key value in ReflectFrom, MapTo and StrictMapTo, as a field, a pointer field or a slice element. List, ValidList, StrictList, In and Range use UnmarshalINI too. An error leaves the field unchanged, and StrictMapTo, StrictList and ReflectFrom return it. A struct type that implements either interface maps to a key instead of a section, so types such as a host:port pair can be one value.
unknwon
force-pushed
the
v2-marshal-ini
branch
from
November 11, 2026 05:02
f41421d to
e40ce90
Compare
A slice type with only MarshalINI lost list reading, and one with only UnmarshalINI lost list writing. A struct type with only one of them could no longer be read or written as a section. Both now keep their usual mapping unless they implement both methods. Also correct the docs of errors in slice elements, the generic accessors, which take Scalar types, and Scalar types with UnmarshalINI.
A map or array type with only MarshalINI was written by ReflectFrom but skipped by MapTo without an error. Only string, boolean and number types, whose kind handles the other direction, now map to a key with one method.
Section.ReflectFrom on a file with AllowNonUniqueSections rejected a pointer to a struct type with MarshalINI and UnmarshalINI, while MapTo accepted it. A nonunique field or a value passed for such a section now maps any struct type but time.Time to sections, in both directions.
TestStructMappingMatrix maps types of each kind that struct mapping treats differently, with no methods, either method, or both, in every field shape: plain, pointer, slice, allowshadow, delim, in a section, nonunique, embedded, extends, and passed for a section. Each must round trip through ReflectFrom, Write and MapTo, or be unsupported in both directions. Rows for types without both methods match v2. It found one more mismatch, which v2 already had: a pointer to a slice was written as the slice but couldn't be read. It now reads as one. FuzzStructMapping also gets custom struct, slice and map fields, a pointer to a slice, and custom nonunique sections.
ReflectFrom wrote a **T field as the value it points to, but MapTo rejected it, as it already did on v2. MapTo now reads any depth of pointers, keeping how a single pointer reads: a value that doesn't parse leaves it as it is. The matrix test gets pointer to pointer, array and interface fields, and array types with and without the methods.
They were written but not read on v2 too, and nobody asked for them, so they stay that way. The matrix test expects exactly those cases to be written but not read, and the fuzzer drops their fields.
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.
Describe the pull request
Types can now format and parse their own key values:
Where they apply
MapToandStrictMapTocallUnmarshalINIwith the value asKey.Stringreturns it, for a plain field, a pointer field, and each element of a slice field.List,ValidList,StrictList,InandRangecall it too for aScalartype, soini.List[Permission](k, ",")works for a namedintenum.ReflectFromcallsMarshalINIfor the same kinds of field, with either a value or a pointer receiver.UnmarshalINIis handled like a value that doesn't parse.MapToleaves a field unchanged and makes a failing slice element the zero value.StrictMapToandStrictListreturn the error.ReflectFromreturns an error fromMarshalINI.Rules
intenum withUnmarshalINIreadsPerm = writeinstead of failing on a non-number.host:portpair can be one value. With only one of them, a struct still maps to a section, a slice to a list, and other types stay unsupported, in both directions. A struct that embeds a type with both methods gets them, and so maps to one key too. Where sections are asked for explicitly, by anonuniquefield or a value passed to a section of a file withAllowNonUniqueSections, any struct type still maps to sections.time.Timekeeps its own handling.Tests
TestMarshalerUnmarshalercovers an enum and a struct type: reading, writing and reading back, errors inMapTo,StrictMapToandReflectFrom, and the generic accessors. A fifth subtest checks that slice, struct and map types with only one method keep their usual mapping. Each subtest fails without the change it covers.TestStructMappingMatrixmaps a number, struct, slice, map and array type, each with no methods, either method, or both, in every field shape: plain, pointer, pointer to pointer, slice, array, interface,allowshadow,delim, in a section,nonunique, embedded,extends, and passed for a section. Each must round trip throughReflectFrom,WriteandMapTo, or be unsupported in both directions. The rows for types without both methods matchv2. Two cases are written but not read, as onv2, and the test expects exactly those: a pointer to a slice, and a pointer to a pointer.FuzzStructMappingnow has enum, custom struct, slice and map fields, and customnonuniquesections. A 45-second run found nothing.Link to the issue: #353
Checklist
AI usage
Claude Code ran the self-review (bugs, docs, security and repository rules, each by a separate review agent) and wrote the follow-up commits
68f90c3,d679f6c,346a07c,f838383,2a7d2c1,9a4d4b8and the revert of the last two's read support, which fix the one-method slice, struct, map and array cases, custom struct types where sections are asked for, and the doc inaccuracies those reviews found, and add the matrix test.