Skip to content

Commit b99e8db

Browse files
pelletierclaude
andauthored
docs: remove "Migrating from v1" section from README (#1070)
The migration guidance has outlived its usefulness now that v2 has been the recommended version for a long time. Drop the section to keep the README focused on current usage. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 5a548e3 commit b99e8db

1 file changed

Lines changed: 0 additions & 298 deletions

File tree

README.md

Lines changed: 0 additions & 298 deletions
Original file line numberDiff line numberDiff line change
@@ -314,304 +314,6 @@ Multiple versions are available on [ghcr.io][docker].
314314

315315
[docker]: https://github.com/pelletier/go-toml/pkgs/container/go-toml
316316

317-
## Migrating from v1
318-
319-
This section describes the differences between v1 and v2, with some pointers on
320-
how to get the original behavior when possible.
321-
322-
### Decoding / Unmarshal
323-
324-
#### Automatic field name guessing
325-
326-
When unmarshaling to a struct, if a key in the TOML document does not exactly
327-
match the name of a struct field or any of the `toml`-tagged field, v1 tries
328-
multiple variations of the key ([code][v1-keys]).
329-
330-
V2 instead does a case-insensitive matching, like `encoding/json`.
331-
332-
This could impact you if you are relying on casing to differentiate two fields,
333-
and one of them is a not using the `toml` struct tag. The recommended solution
334-
is to be specific about tag names for those fields using the `toml` struct tag.
335-
336-
[v1-keys]: https://github.com/pelletier/go-toml/blob/a2e52561804c6cd9392ebf0048ca64fe4af67a43/marshal.go#L775-L781
337-
338-
#### Ignore preexisting value in interface
339-
340-
When decoding into a non-nil `interface{}`, go-toml v1 uses the type of the
341-
element in the interface to decode the object. For example:
342-
343-
```go
344-
type inner struct {
345-
B interface{}
346-
}
347-
type doc struct {
348-
A interface{}
349-
}
350-
351-
d := doc{
352-
A: inner{
353-
B: "Before",
354-
},
355-
}
356-
357-
data := `
358-
[A]
359-
B = "After"
360-
`
361-
362-
toml.Unmarshal([]byte(data), &d)
363-
fmt.Printf("toml v1: %#v\n", d)
364-
365-
// toml v1: main.doc{A:main.inner{B:"After"}}
366-
```
367-
368-
In this case, field `A` is of type `interface{}`, containing a `inner` struct.
369-
V1 sees that type and uses it when decoding the object.
370-
371-
When decoding an object into an `interface{}`, V2 instead disregards whatever
372-
value the `interface{}` may contain and replaces it with a
373-
`map[string]interface{}`. With the same data structure as above, here is what
374-
the result looks like:
375-
376-
```go
377-
toml.Unmarshal([]byte(data), &d)
378-
fmt.Printf("toml v2: %#v\n", d)
379-
380-
// toml v2: main.doc{A:map[string]interface {}{"B":"After"}}
381-
```
382-
383-
This is to match `encoding/json`'s behavior. There is no way to make the v2
384-
decoder behave like v1.
385-
386-
#### Values out of array bounds ignored
387-
388-
When decoding into an array, v1 returns an error when the number of elements
389-
contained in the doc is superior to the capacity of the array. For example:
390-
391-
```go
392-
type doc struct {
393-
A [2]string
394-
}
395-
d := doc{}
396-
err := toml.Unmarshal([]byte(`A = ["one", "two", "many"]`), &d)
397-
fmt.Println(err)
398-
399-
// (1, 1): unmarshal: TOML array length (3) exceeds destination array length (2)
400-
```
401-
402-
In the same situation, v2 ignores the last value:
403-
404-
```go
405-
err := toml.Unmarshal([]byte(`A = ["one", "two", "many"]`), &d)
406-
fmt.Println("err:", err, "d:", d)
407-
// err: <nil> d: {[one two]}
408-
```
409-
410-
This is to match `encoding/json`'s behavior. There is no way to make the v2
411-
decoder behave like v1.
412-
413-
#### Support for `toml.Unmarshaler` has been dropped
414-
415-
This method was not widely used, poorly defined, and added a lot of complexity.
416-
A similar effect can be achieved by implementing the `encoding.TextUnmarshaler`
417-
interface and use strings.
418-
419-
#### Support for `default` struct tag has been dropped
420-
421-
This feature adds complexity and a poorly defined API for an effect that can be
422-
accomplished outside of the library.
423-
424-
It does not seem like other format parsers in Go support that feature (the
425-
project referenced in the original ticket #202 has not been updated since 2017).
426-
Given that go-toml v2 should not touch values not in the document, the same
427-
effect can be achieved by pre-filling the struct with defaults (libraries like
428-
[go-defaults][go-defaults] can help). Also, string representation is not well
429-
defined for all types: it creates issues like #278.
430-
431-
The recommended replacement is pre-filling the struct before unmarshaling.
432-
433-
[go-defaults]: https://github.com/mcuadros/go-defaults
434-
435-
#### `toml.Tree` replacement
436-
437-
This structure was the initial attempt at providing a document model for
438-
go-toml. It allows manipulating the structure of any document, encoding and
439-
decoding from their TOML representation. While a more robust feature was
440-
initially planned in go-toml v2, this has been ultimately [removed from
441-
scope][nodoc] of this library, with no plan to add it back at the moment. The
442-
closest equivalent at the moment would be to unmarshal into an `interface{}` and
443-
use type assertions and/or reflection to manipulate the arbitrary
444-
structure. However this would fall short of providing all of the TOML features
445-
such as adding comments and be specific about whitespace.
446-
447-
448-
#### `toml.Position` are not retrievable anymore
449-
450-
The API for retrieving the position (line, column) of a specific TOML element do
451-
not exist anymore. This was done to minimize the amount of concepts introduced
452-
by the library (query path), and avoid the performance hit related to storing
453-
positions in the absence of a document model, for a feature that seemed to have
454-
little use. Errors however have gained more detailed position
455-
information. Position retrieval seems better fitted for a document model, which
456-
has been [removed from the scope][nodoc] of go-toml v2 at the moment.
457-
458-
### Encoding / Marshal
459-
460-
#### Default struct fields order
461-
462-
V1 emits struct fields order alphabetically by default. V2 struct fields are
463-
emitted in order they are defined. For example:
464-
465-
```go
466-
type S struct {
467-
B string
468-
A string
469-
}
470-
471-
data := S{
472-
B: "B",
473-
A: "A",
474-
}
475-
476-
b, _ := tomlv1.Marshal(data)
477-
fmt.Println("v1:\n" + string(b))
478-
479-
b, _ = tomlv2.Marshal(data)
480-
fmt.Println("v2:\n" + string(b))
481-
482-
// Output:
483-
// v1:
484-
// A = "A"
485-
// B = "B"
486-
487-
// v2:
488-
// B = 'B'
489-
// A = 'A'
490-
```
491-
492-
There is no way to make v2 encoder behave like v1. A workaround could be to
493-
manually sort the fields alphabetically in the struct definition, or generate
494-
struct types using `reflect.StructOf`.
495-
496-
#### No indentation by default
497-
498-
V1 automatically indents content of tables by default. V2 does not. However the
499-
same behavior can be obtained using [`Encoder.SetIndentTables`][sit]. For example:
500-
501-
```go
502-
data := map[string]interface{}{
503-
"table": map[string]string{
504-
"key": "value",
505-
},
506-
}
507-
508-
b, _ := tomlv1.Marshal(data)
509-
fmt.Println("v1:\n" + string(b))
510-
511-
b, _ = tomlv2.Marshal(data)
512-
fmt.Println("v2:\n" + string(b))
513-
514-
buf := bytes.Buffer{}
515-
enc := tomlv2.NewEncoder(&buf)
516-
enc.SetIndentTables(true)
517-
enc.Encode(data)
518-
fmt.Println("v2 Encoder:\n" + string(buf.Bytes()))
519-
520-
// Output:
521-
// v1:
522-
//
523-
// [table]
524-
// key = "value"
525-
//
526-
// v2:
527-
// [table]
528-
// key = 'value'
529-
//
530-
//
531-
// v2 Encoder:
532-
// [table]
533-
// key = 'value'
534-
```
535-
536-
[sit]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#Encoder.SetIndentTables
537-
538-
#### Keys and strings are single quoted
539-
540-
V1 always uses double quotes (`"`) around strings and keys that cannot be
541-
represented bare (unquoted). V2 uses single quotes instead by default (`'`),
542-
unless a character cannot be represented, then falls back to double quotes. As a
543-
result of this change, `Encoder.QuoteMapKeys` has been removed, as it is not
544-
useful anymore.
545-
546-
There is no way to make v2 encoder behave like v1.
547-
548-
#### `TextMarshaler` emits as a string, not TOML
549-
550-
Types that implement [`encoding.TextMarshaler`][tm] can emit arbitrary TOML in
551-
v1. The encoder would append the result to the output directly. In v2 the result
552-
is wrapped in a string. As a result, this interface cannot be implemented by the
553-
root object.
554-
555-
There is no way to make v2 encoder behave like v1.
556-
557-
[tm]: https://golang.org/pkg/encoding/#TextMarshaler
558-
559-
#### `Encoder.CompactComments` has been removed
560-
561-
Emitting compact comments is now the default behavior of go-toml. This option
562-
is not necessary anymore.
563-
564-
#### Struct tags have been merged
565-
566-
V1 used to provide multiple struct tags: `comment`, `commented`, `multiline`,
567-
`toml`, and `omitempty`. To behave more like the standard library, v2 has merged
568-
`toml`, `multiline`, `commented`, and `omitempty`. For example:
569-
570-
```go
571-
type doc struct {
572-
// v1
573-
F string `toml:"field" multiline:"true" omitempty:"true" commented:"true"`
574-
// v2
575-
F string `toml:"field,multiline,omitempty,commented"`
576-
}
577-
```
578-
579-
Has a result, the `Encoder.SetTag*` methods have been removed, as there is just
580-
one tag now.
581-
582-
#### `Encoder.ArraysWithOneElementPerLine` has been renamed
583-
584-
The new name is `Encoder.SetArraysMultiline`. The behavior should be the same.
585-
586-
#### `Encoder.Indentation` has been renamed
587-
588-
The new name is `Encoder.SetIndentSymbol`. The behavior should be the same.
589-
590-
591-
#### Embedded structs behave like stdlib
592-
593-
V1 defaults to merging embedded struct fields into the embedding struct. This
594-
behavior was unexpected because it does not follow the standard library. To
595-
avoid breaking backward compatibility, the `Encoder.PromoteAnonymous` method was
596-
added to make the encoder behave correctly. Given backward compatibility is not
597-
a problem anymore, v2 does the right thing by default: it follows the behavior
598-
of `encoding/json`. `Encoder.PromoteAnonymous` has been removed.
599-
600-
[nodoc]: https://github.com/pelletier/go-toml/discussions/506#discussioncomment-1526038
601-
602-
### `query`
603-
604-
go-toml v1 provided the [`go-toml/query`][query] package. It allowed to run
605-
JSONPath-style queries on TOML files. This feature is not available in v2. For a
606-
replacement, check out [dasel][dasel].
607-
608-
This package has been removed because it was essentially not supported anymore
609-
(last commit May 2020), increased the complexity of the code base, and more
610-
complete solutions exist out there.
611-
612-
[query]: https://github.com/pelletier/go-toml/tree/f99d6bbca119636aeafcf351ee52b3d202782627/query
613-
[dasel]: https://github.com/TomWright/dasel
614-
615317
## Versioning
616318

617319
Expect for parts explicitly marked otherwise, go-toml follows [Semantic

0 commit comments

Comments
 (0)