strict.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package toml
  2. import (
  3. "github.com/pelletier/go-toml/v2/internal/danger"
  4. "github.com/pelletier/go-toml/v2/internal/tracker"
  5. "github.com/pelletier/go-toml/v2/unstable"
  6. )
  7. type strict struct {
  8. Enabled bool
  9. // Tracks the current key being processed.
  10. key tracker.KeyTracker
  11. missing []unstable.ParserError
  12. }
  13. func (s *strict) EnterTable(node *unstable.Node) {
  14. if !s.Enabled {
  15. return
  16. }
  17. s.key.UpdateTable(node)
  18. }
  19. func (s *strict) EnterArrayTable(node *unstable.Node) {
  20. if !s.Enabled {
  21. return
  22. }
  23. s.key.UpdateArrayTable(node)
  24. }
  25. func (s *strict) EnterKeyValue(node *unstable.Node) {
  26. if !s.Enabled {
  27. return
  28. }
  29. s.key.Push(node)
  30. }
  31. func (s *strict) ExitKeyValue(node *unstable.Node) {
  32. if !s.Enabled {
  33. return
  34. }
  35. s.key.Pop(node)
  36. }
  37. func (s *strict) MissingTable(node *unstable.Node) {
  38. if !s.Enabled {
  39. return
  40. }
  41. s.missing = append(s.missing, unstable.ParserError{
  42. Highlight: keyLocation(node),
  43. Message: "missing table",
  44. Key: s.key.Key(),
  45. })
  46. }
  47. func (s *strict) MissingField(node *unstable.Node) {
  48. if !s.Enabled {
  49. return
  50. }
  51. s.missing = append(s.missing, unstable.ParserError{
  52. Highlight: keyLocation(node),
  53. Message: "missing field",
  54. Key: s.key.Key(),
  55. })
  56. }
  57. func (s *strict) Error(doc []byte) error {
  58. if !s.Enabled || len(s.missing) == 0 {
  59. return nil
  60. }
  61. err := &StrictMissingError{
  62. Errors: make([]DecodeError, 0, len(s.missing)),
  63. }
  64. for _, derr := range s.missing {
  65. derr := derr
  66. err.Errors = append(err.Errors, *wrapDecodeError(doc, &derr))
  67. }
  68. return err
  69. }
  70. func keyLocation(node *unstable.Node) []byte {
  71. k := node.Key()
  72. hasOne := k.Next()
  73. if !hasOne {
  74. panic("should not be called with empty key")
  75. }
  76. start := k.Node().Data
  77. end := k.Node().Data
  78. for k.Next() {
  79. end = k.Node().Data
  80. }
  81. return danger.BytesRange(start, end)
  82. }