...
1
16
17 package recognizer
18
19 import (
20 "fmt"
21
22 "k8s.io/apimachinery/pkg/runtime"
23 "k8s.io/apimachinery/pkg/runtime/schema"
24 )
25
26 type RecognizingDecoder interface {
27 runtime.Decoder
28
29
30
31
32
33
34
35 RecognizesData(peek []byte) (ok, unknown bool, err error)
36 }
37
38
39
40
41
42
43
44
45 func NewDecoder(decoders ...runtime.Decoder) runtime.Decoder {
46 return &decoder{
47 decoders: decoders,
48 }
49 }
50
51 type decoder struct {
52 decoders []runtime.Decoder
53 }
54
55 var _ RecognizingDecoder = &decoder{}
56
57 func (d *decoder) RecognizesData(data []byte) (bool, bool, error) {
58 var (
59 lastErr error
60 anyUnknown bool
61 )
62 for _, r := range d.decoders {
63 switch t := r.(type) {
64 case RecognizingDecoder:
65 ok, unknown, err := t.RecognizesData(data)
66 if err != nil {
67 lastErr = err
68 continue
69 }
70 anyUnknown = anyUnknown || unknown
71 if !ok {
72 continue
73 }
74 return true, false, nil
75 }
76 }
77 return false, anyUnknown, lastErr
78 }
79
80 func (d *decoder) Decode(data []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
81 var (
82 lastErr error
83 skipped []runtime.Decoder
84 )
85
86
87 for _, r := range d.decoders {
88 switch t := r.(type) {
89 case RecognizingDecoder:
90 ok, unknown, err := t.RecognizesData(data)
91 if err != nil {
92 lastErr = err
93 continue
94 }
95 if unknown {
96 skipped = append(skipped, t)
97 continue
98 }
99 if !ok {
100 continue
101 }
102 return r.Decode(data, gvk, into)
103 default:
104 skipped = append(skipped, t)
105 }
106 }
107
108
109 for _, r := range skipped {
110 out, actual, err := r.Decode(data, gvk, into)
111 if err != nil {
112
113
114
115
116 if out == nil || !runtime.IsStrictDecodingError(err) {
117 lastErr = err
118 continue
119 }
120 }
121 return out, actual, err
122 }
123
124 if lastErr == nil {
125 lastErr = fmt.Errorf("no serialization format matched the provided data")
126 }
127 return nil, nil, lastErr
128 }
129
View as plain text