fix(decode): decode into a defined string or bool type
Assisted-by: DeepSeek V4.1 Flash
This commit is contained in:
@@ -23,6 +23,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
every major version 2 module: imports change to
|
every major version 2 module: imports change to
|
||||||
`sourcedock.dev/petrbalvin/interpres/v2`.
|
`sourcedock.dev/petrbalvin/interpres/v2`.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Decoding into a defined type whose underlying kind is string or bool, such
|
||||||
|
as `type Name string`, panicked instead of storing the value, because a
|
||||||
|
value of the predeclared type is not assignable to a defined type and the
|
||||||
|
decoder assigned it without a conversion.
|
||||||
|
|
||||||
## [1.1.0] - 2026-09-18
|
## [1.1.0] - 2026-09-18
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -202,7 +202,10 @@ func setBasic(dst, val reflect.Value, kind string) error {
|
|||||||
if dst.Kind() != val.Kind() {
|
if dst.Kind() != val.Kind() {
|
||||||
return fmt.Errorf("interpres: cannot assign %s to %s", kind, dst.Type())
|
return fmt.Errorf("interpres: cannot assign %s to %s", kind, dst.Type())
|
||||||
}
|
}
|
||||||
dst.Set(val)
|
// Convert rather than assign: a value of the predeclared type is not
|
||||||
|
// assignable to a defined type of the same kind, so a plain Set panics on
|
||||||
|
// a destination such as `type Name string`.
|
||||||
|
dst.Set(val.Convert(dst.Type()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -725,3 +725,25 @@ func TestDecodeErrorOnMapDestination(t *testing.T) {
|
|||||||
t.Fatalf("Path = %v", de.Path)
|
t.Fatalf("Path = %v", de.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalIntoDefinedScalarTypes(t *testing.T) {
|
||||||
|
// A defined type whose underlying kind is string or bool takes the value.
|
||||||
|
// A bare reflect Set panics on such a type, because a string is not
|
||||||
|
// assignable to a defined string type without a conversion.
|
||||||
|
type Name string
|
||||||
|
type Flag bool
|
||||||
|
type Cfg struct {
|
||||||
|
N Name `toml:"n"`
|
||||||
|
F Flag `toml:"f"`
|
||||||
|
}
|
||||||
|
var cfg Cfg
|
||||||
|
if err := Unmarshal([]byte("n = \"x\"\nf = true\n"), &cfg); err != nil {
|
||||||
|
t.Fatalf("unmarshal: %v", err)
|
||||||
|
}
|
||||||
|
if cfg.N != "x" {
|
||||||
|
t.Errorf("N = %q, want \"x\"", cfg.N)
|
||||||
|
}
|
||||||
|
if !cfg.F {
|
||||||
|
t.Error("F = false, want true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user