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