Compare commits
15 Commits
v2.0.0-beta.8
...
v2.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 216628222f | |||
| 322e0b15d2 | |||
| 85bfc0ed51 | |||
| 295a720dfb | |||
| 0a422e3dbd | |||
| 627dade0c7 | |||
| b2e0231cc9 | |||
| ba95863cd3 | |||
| db679df765 | |||
| c5ca2c682b | |||
| ed80712cb4 | |||
| b24772942d | |||
| 9501a05ed7 | |||
| 171a592663 | |||
| 5aaf5ef13b |
@@ -35,11 +35,11 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v1
|
uses: github/codeql-action/init@v2
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@@ -50,7 +50,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v1
|
uses: github/codeql-action/autobuild@v2
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
@@ -64,4 +64,4 @@ jobs:
|
|||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v1
|
uses: github/codeql-action/analyze@v2
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
name: report
|
name: report
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup go
|
- name: Setup go
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
@@ -24,13 +24,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: 1.18
|
go-version: 1.18
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Run GoReleaser
|
- name: Run GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@v2
|
uses: goreleaser/goreleaser-action@v3
|
||||||
with:
|
with:
|
||||||
distribution: goreleaser
|
distribution: goreleaser
|
||||||
version: latest
|
version: latest
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
name: ${{ matrix.go }}/${{ matrix.os }}
|
name: ${{ matrix.go }}/${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup go ${{ matrix.go }}
|
- name: Setup go ${{ matrix.go }}
|
||||||
|
|||||||
@@ -16,7 +16,11 @@ builds:
|
|||||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||||
targets:
|
targets:
|
||||||
- linux_amd64
|
- linux_amd64
|
||||||
|
- linux_arm64
|
||||||
|
- linux_arm
|
||||||
- windows_amd64
|
- windows_amd64
|
||||||
|
- windows_arm64
|
||||||
|
- windows_arm
|
||||||
- darwin_amd64
|
- darwin_amd64
|
||||||
- darwin_arm64
|
- darwin_arm64
|
||||||
- id: tomljson
|
- id: tomljson
|
||||||
@@ -31,7 +35,11 @@ builds:
|
|||||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||||
targets:
|
targets:
|
||||||
- linux_amd64
|
- linux_amd64
|
||||||
|
- linux_arm64
|
||||||
|
- linux_arm
|
||||||
- windows_amd64
|
- windows_amd64
|
||||||
|
- windows_arm64
|
||||||
|
- windows_arm
|
||||||
- darwin_amd64
|
- darwin_amd64
|
||||||
- darwin_arm64
|
- darwin_arm64
|
||||||
- id: jsontoml
|
- id: jsontoml
|
||||||
@@ -46,7 +54,11 @@ builds:
|
|||||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||||
targets:
|
targets:
|
||||||
- linux_amd64
|
- linux_amd64
|
||||||
|
- linux_arm64
|
||||||
|
- linux_arm
|
||||||
- windows_amd64
|
- windows_amd64
|
||||||
|
- windows_arm64
|
||||||
|
- windows_arm
|
||||||
- darwin_amd64
|
- darwin_amd64
|
||||||
- darwin_arm64
|
- darwin_arm64
|
||||||
universal_binaries:
|
universal_binaries:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2013 - 2021 Thomas Pelletier, Eric Anderton
|
Copyright (c) 2013 - 2022 Thomas Pelletier, Eric Anderton
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -4,17 +4,6 @@ Go library for the [TOML](https://toml.io/en/) format.
|
|||||||
|
|
||||||
This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0).
|
This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0).
|
||||||
|
|
||||||
## Development status
|
|
||||||
|
|
||||||
This is the upcoming major version of go-toml. It is currently in active
|
|
||||||
development. As of release v2.0.0-beta.1, the library has reached feature parity
|
|
||||||
with v1, and fixes a lot known bugs and performance issues along the way.
|
|
||||||
|
|
||||||
If you do not need the advanced document editing features of v1, you are
|
|
||||||
encouraged to try out this version.
|
|
||||||
|
|
||||||
[👉 Roadmap for v2](https://github.com/pelletier/go-toml/discussions/506)
|
|
||||||
|
|
||||||
[🐞 Bug Reports](https://github.com/pelletier/go-toml/issues)
|
[🐞 Bug Reports](https://github.com/pelletier/go-toml/issues)
|
||||||
|
|
||||||
[💬 Anything else](https://github.com/pelletier/go-toml/discussions)
|
[💬 Anything else](https://github.com/pelletier/go-toml/discussions)
|
||||||
@@ -49,7 +38,7 @@ operations should not be shockingly slow. See [benchmarks](#benchmarks).
|
|||||||
### Strict mode
|
### Strict mode
|
||||||
|
|
||||||
`Decoder` can be set to "strict mode", which makes it error when some parts of
|
`Decoder` can be set to "strict mode", which makes it error when some parts of
|
||||||
the TOML document was not prevent in the target structure. This is a great way
|
the TOML document was not present in the target structure. This is a great way
|
||||||
to check for typos. [See example in the documentation][strict].
|
to check for typos. [See example in the documentation][strict].
|
||||||
|
|
||||||
[strict]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#example-Decoder.DisallowUnknownFields
|
[strict]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#example-Decoder.DisallowUnknownFields
|
||||||
@@ -551,6 +540,13 @@ complete solutions exist out there.
|
|||||||
[query]: https://github.com/pelletier/go-toml/tree/f99d6bbca119636aeafcf351ee52b3d202782627/query
|
[query]: https://github.com/pelletier/go-toml/tree/f99d6bbca119636aeafcf351ee52b3d202782627/query
|
||||||
[dasel]: https://github.com/TomWright/dasel
|
[dasel]: https://github.com/TomWright/dasel
|
||||||
|
|
||||||
|
## Versioning
|
||||||
|
|
||||||
|
Go-toml follows [Semantic Versioning](http://semver.org/). The supported version
|
||||||
|
of [TOML](https://github.com/toml-lang/toml) is indicated at the beginning of
|
||||||
|
this document. The last two major versions of Go are supported
|
||||||
|
(see [Go Release Policy](https://golang.org/doc/devel/release.html#policy)).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
The MIT License (MIT). Read [LICENSE](LICENSE).
|
The MIT License (MIT). Read [LICENSE](LICENSE).
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ module github.com/pelletier/go-toml/v2
|
|||||||
|
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require github.com/stretchr/testify v1.7.1
|
require github.com/stretchr/testify v1.7.2
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
@@ -11,5 +11,6 @@ func TestEntrySize(t *testing.T) {
|
|||||||
// Validate no regression on the size of entry{}. This is a critical bit for
|
// Validate no regression on the size of entry{}. This is a critical bit for
|
||||||
// performance of unmarshaling documents. Should only be increased with care
|
// performance of unmarshaling documents. Should only be increased with care
|
||||||
// and a very good reason.
|
// and a very good reason.
|
||||||
require.LessOrEqual(t, 48, int(unsafe.Sizeof(entry{})))
|
maxExpectedEntrySize := 48
|
||||||
|
require.LessOrEqual(t, int(unsafe.Sizeof(entry{})), maxExpectedEntrySize)
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-4
@@ -107,6 +107,13 @@ func (enc *Encoder) SetIndentTables(indent bool) *Encoder {
|
|||||||
// a newline character or a single quote. In that case they are emitted as
|
// a newline character or a single quote. In that case they are emitted as
|
||||||
// quoted strings.
|
// quoted strings.
|
||||||
//
|
//
|
||||||
|
// Unsigned integers larger than math.MaxInt64 cannot be encoded. Doing so
|
||||||
|
// results in an error. This rule exists because the TOML specification only
|
||||||
|
// requires parsers to support at least the 64 bits integer range. Allowing
|
||||||
|
// larger numbers would create non-standard TOML documents, which may not be
|
||||||
|
// readable (at best) by other implementations. To encode such numbers, a
|
||||||
|
// solution is a custom type that implements encoding.TextMarshaler.
|
||||||
|
//
|
||||||
// When encoding structs, fields are encoded in order of definition, with their
|
// When encoding structs, fields are encoded in order of definition, with their
|
||||||
// exact name.
|
// exact name.
|
||||||
//
|
//
|
||||||
@@ -128,7 +135,8 @@ func (enc *Encoder) SetIndentTables(indent bool) *Encoder {
|
|||||||
//
|
//
|
||||||
// In addition to the "toml" tag struct tag, a "comment" tag can be used to emit
|
// In addition to the "toml" tag struct tag, a "comment" tag can be used to emit
|
||||||
// a TOML comment before the value being annotated. Comments are ignored inside
|
// a TOML comment before the value being annotated. Comments are ignored inside
|
||||||
// inline tables.
|
// inline tables. For array tables, the comment is only present before the first
|
||||||
|
// element of the array.
|
||||||
func (enc *Encoder) Encode(v interface{}) error {
|
func (enc *Encoder) Encode(v interface{}) error {
|
||||||
var (
|
var (
|
||||||
b []byte
|
b []byte
|
||||||
@@ -302,7 +310,11 @@ func (enc *Encoder) encode(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, e
|
|||||||
b = append(b, "false"...)
|
b = append(b, "false"...)
|
||||||
}
|
}
|
||||||
case reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint:
|
case reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint:
|
||||||
b = strconv.AppendUint(b, v.Uint(), 10)
|
x := v.Uint()
|
||||||
|
if x > uint64(math.MaxInt64) {
|
||||||
|
return nil, fmt.Errorf("toml: not encoding uint (%d) greater than max int64 (%d)", x, int64(math.MaxInt64))
|
||||||
|
}
|
||||||
|
b = strconv.AppendUint(b, x, 10)
|
||||||
case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int:
|
case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int:
|
||||||
b = strconv.AppendInt(b, v.Int(), 10)
|
b = strconv.AppendInt(b, v.Int(), 10)
|
||||||
default:
|
default:
|
||||||
@@ -652,10 +664,19 @@ func (enc *Encoder) encodeStruct(b []byte, ctx encoderCtx, v reflect.Value) ([]b
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (enc *Encoder) encodeComment(indent int, comment string, b []byte) []byte {
|
func (enc *Encoder) encodeComment(indent int, comment string, b []byte) []byte {
|
||||||
if comment != "" {
|
for len(comment) > 0 {
|
||||||
|
var line string
|
||||||
|
idx := strings.IndexByte(comment, '\n')
|
||||||
|
if idx >= 0 {
|
||||||
|
line = comment[:idx]
|
||||||
|
comment = comment[idx+1:]
|
||||||
|
} else {
|
||||||
|
line = comment
|
||||||
|
comment = ""
|
||||||
|
}
|
||||||
b = enc.indent(indent, b)
|
b = enc.indent(indent, b)
|
||||||
b = append(b, "# "...)
|
b = append(b, "# "...)
|
||||||
b = append(b, comment...)
|
b = append(b, line...)
|
||||||
b = append(b, '\n')
|
b = append(b, '\n')
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
@@ -881,6 +902,8 @@ func (enc *Encoder) encodeSliceAsArrayTable(b []byte, ctx encoderCtx, v reflect.
|
|||||||
scratch = append(scratch, "]]\n"...)
|
scratch = append(scratch, "]]\n"...)
|
||||||
ctx.skipTableHeader = true
|
ctx.skipTableHeader = true
|
||||||
|
|
||||||
|
b = enc.encodeComment(ctx.indent, ctx.options.comment, b)
|
||||||
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
for i := 0; i < v.Len(); i++ {
|
||||||
b = append(b, scratch...)
|
b = append(b, scratch...)
|
||||||
|
|
||||||
|
|||||||
@@ -1004,6 +1004,22 @@ func TestIssue752(t *testing.T) {
|
|||||||
require.Equal(t, "", string(out))
|
require.Equal(t, "", string(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIssue768(t *testing.T) {
|
||||||
|
type cfg struct {
|
||||||
|
Name string `comment:"This is a multiline comment.\nThis is line 2."`
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := toml.Marshal(&cfg{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expected := `# This is a multiline comment.
|
||||||
|
# This is line 2.
|
||||||
|
Name = ''
|
||||||
|
`
|
||||||
|
|
||||||
|
require.Equal(t, expected, string(out))
|
||||||
|
}
|
||||||
|
|
||||||
func TestMarshalNestedAnonymousStructs(t *testing.T) {
|
func TestMarshalNestedAnonymousStructs(t *testing.T) {
|
||||||
type Embedded struct {
|
type Embedded struct {
|
||||||
Value string `toml:"value" json:"value"`
|
Value string `toml:"value" json:"value"`
|
||||||
@@ -1086,6 +1102,19 @@ func TestLocalTime(t *testing.T) {
|
|||||||
require.Equal(t, expected, string(out))
|
require.Equal(t, expected, string(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMarshalUint64Overflow(t *testing.T) {
|
||||||
|
// The TOML spec only requires implementation to provide support for the
|
||||||
|
// int64 range. To avoid generating TOML documents that would not be
|
||||||
|
// supported by standard-compliant parsers, uint64 > max int64 cannot be
|
||||||
|
// marshaled.
|
||||||
|
x := map[string]interface{}{
|
||||||
|
"foo": uint64(math.MaxInt64) + 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := toml.Marshal(x)
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleMarshal() {
|
func ExampleMarshal() {
|
||||||
type MyConfig struct {
|
type MyConfig struct {
|
||||||
Version int
|
Version int
|
||||||
|
|||||||
+25
-9
@@ -866,12 +866,27 @@ func (d *decoder) unmarshalFloat(value *ast.Node, v reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
|
const (
|
||||||
const (
|
|
||||||
maxInt = int64(^uint(0) >> 1)
|
maxInt = int64(^uint(0) >> 1)
|
||||||
minInt = -maxInt - 1
|
minInt = -maxInt - 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Maximum value of uint for decoding. Currently the decoder parses the integer
|
||||||
|
// into an int64. As a result, on architectures where uint is 64 bits, the
|
||||||
|
// effective maximum uint we can decode is the maximum of int64. On
|
||||||
|
// architectures where uint is 32 bits, the maximum value we can decode is
|
||||||
|
// lower: the maximum of uint32. I didn't find a way to figure out this value at
|
||||||
|
// compile time, so it is computed during initialization.
|
||||||
|
var maxUint int64 = math.MaxInt64
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
m := uint64(^uint(0))
|
||||||
|
if m < uint64(maxUint) {
|
||||||
|
maxUint = int64(m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
|
||||||
i, err := parseInteger(value.Data)
|
i, err := parseInteger(value.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -932,7 +947,7 @@ func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
|
|||||||
|
|
||||||
r = reflect.ValueOf(uint8(i))
|
r = reflect.ValueOf(uint8(i))
|
||||||
case reflect.Uint:
|
case reflect.Uint:
|
||||||
if i < 0 {
|
if i < 0 || i > maxUint {
|
||||||
return fmt.Errorf("toml: negative number %d does not fit in an uint", i)
|
return fmt.Errorf("toml: negative number %d does not fit in an uint", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1167,11 +1182,6 @@ func forEachField(t reflect.Type, path []int, do func(name string, path []int))
|
|||||||
fieldPath := append(path, i)
|
fieldPath := append(path, i)
|
||||||
fieldPath = fieldPath[:len(fieldPath):len(fieldPath)]
|
fieldPath = fieldPath[:len(fieldPath):len(fieldPath)]
|
||||||
|
|
||||||
if f.Anonymous {
|
|
||||||
forEachField(f.Type, fieldPath, do)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
name := f.Tag.Get("toml")
|
name := f.Tag.Get("toml")
|
||||||
if name == "-" {
|
if name == "-" {
|
||||||
continue
|
continue
|
||||||
@@ -1180,6 +1190,12 @@ func forEachField(t reflect.Type, path []int, do func(name string, path []int))
|
|||||||
if i := strings.IndexByte(name, ','); i >= 0 {
|
if i := strings.IndexByte(name, ','); i >= 0 {
|
||||||
name = name[:i]
|
name = name[:i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.Anonymous && name == "" {
|
||||||
|
forEachField(f.Type, fieldPath, do)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if name == "" {
|
if name == "" {
|
||||||
name = f.Name
|
name = f.Name
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2380,6 +2380,49 @@ func TestIssue714(t *testing.T) {
|
|||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIssue772(t *testing.T) {
|
||||||
|
type FileHandling struct {
|
||||||
|
FilePattern string `toml:"pattern"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
FileHandling `toml:"filehandling"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultConfigFile = []byte(`
|
||||||
|
[filehandling]
|
||||||
|
pattern = "reach-masterdev-"`)
|
||||||
|
|
||||||
|
config := Config{}
|
||||||
|
err := toml.Unmarshal(defaultConfigFile, &config)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "reach-masterdev-", config.FileHandling.FilePattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssue774(t *testing.T) {
|
||||||
|
type ScpData struct {
|
||||||
|
Host string `json:"host"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GenConfig struct {
|
||||||
|
SCP []ScpData `toml:"scp" comment:"Array of Secure Copy Configurations"`
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &GenConfig{}
|
||||||
|
c.SCP = []ScpData{{Host: "main.domain.com"}}
|
||||||
|
|
||||||
|
b, err := toml.Marshal(c)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expected := `# Array of Secure Copy Configurations
|
||||||
|
[[scp]]
|
||||||
|
Host = 'main.domain.com'
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
require.Equal(t, expected, string(b))
|
||||||
|
}
|
||||||
|
|
||||||
func TestUnmarshalDecodeErrors(t *testing.T) {
|
func TestUnmarshalDecodeErrors(t *testing.T) {
|
||||||
examples := []struct {
|
examples := []struct {
|
||||||
desc string
|
desc string
|
||||||
|
|||||||
Reference in New Issue
Block a user