A tool for archiving & converting scans of postcards, and information about them.
1package types
2
3import (
4 "fmt"
5 "math/big"
6 "strings"
7 "time"
8
9 "gopkg.in/yaml.v3"
10)
11
12func (f *Flip) UnmarshalYAML(y *yaml.Node) error {
13 if y.ShortTag() != "!!str" {
14 return fmt.Errorf("invalid flip type, expected a string")
15 }
16
17 *f = Flip(y.Value)
18 return nil
19}
20
21// Go doesn't allow falling back on the default, so we have to reimplement the type here 🤦♂️
22type fakeAnnotatedText struct {
23 Text string
24 Annotations []Annotation
25}
26
27func (at *AnnotatedText) UnmarshalYAML(y *yaml.Node) error {
28 if y.ShortTag() == "!!str" {
29 at.Text = y.Value
30 return nil
31 }
32
33 var fake fakeAnnotatedText
34 if err := y.Decode(&fake); err != nil {
35 return err
36 }
37
38 at.Text = fake.Text
39 at.Annotations = fake.Annotations
40 return nil
41}
42
43func (at AnnotatedText) MarshalYAML() (interface{}, error) {
44 if at.Text == "" || len(at.Annotations) == 0 {
45 return at.Text, nil
46 }
47
48 return fakeAnnotatedText{
49 Text: at.Text,
50 Annotations: at.Annotations,
51 }, nil
52}
53
54func (poly Polygon) MarshalYAML() (interface{}, error) {
55 secret := SecretPolygon{
56 Type: "polygon",
57 Prehidden: poly.Prehidden,
58 Points: poly.Points,
59 }
60
61 return secret, nil
62}
63
64func (poly *Polygon) UnmarshalYAML(y *yaml.Node) error {
65 return poly.multiPolygonUnmarshaller(func(into interface{}) error {
66 return y.Decode(into)
67 })
68}
69
70func (p Point) MarshalYAML() (interface{}, error) {
71 node := yaml.Node{
72 Kind: yaml.SequenceNode,
73 Style: yaml.FlowStyle,
74 Content: make([]*yaml.Node, 2),
75 }
76
77 vals := []string{fmt.Sprintf("%f", p.X), fmt.Sprintf("%f", p.Y)}
78
79 for i, val := range vals {
80 node.Content[i] = &yaml.Node{
81 Kind: yaml.ScalarNode,
82 Value: val,
83 }
84 }
85
86 return &node, nil
87}
88
89func (p *Point) UnmarshalYAML(y *yaml.Node) error {
90 var floats []float64
91 if err := y.Decode(&floats); err != nil {
92 return err
93 }
94 if len(floats) != 2 {
95 return fmt.Errorf("incorrect number of floats for point; wanted 2, got %d", len(floats))
96 }
97
98 p.X = floats[0]
99 p.Y = floats[1]
100
101 return nil
102}
103
104func (s Size) MarshalYAML() (interface{}, error) {
105 w, _ := s.CmWidth.Float64()
106 h, _ := s.CmHeight.Float64()
107 return fmt.Sprintf("%.2fcm x %.2fcm", w, h), nil
108}
109
110func (s *Size) UnmarshalYAML(y *yaml.Node) error {
111 if y.ShortTag() != "!!str" {
112 return fmt.Errorf("invalid front_size, expected a string")
113 }
114
115 var w, h big.Rat
116 _, err := fmt.Sscanf(y.Value, "%fcm x %fcm", &w, &h)
117 if err != nil {
118 return err
119 }
120
121 newSize := &Size{
122 CmWidth: &w,
123 CmHeight: &h,
124 }
125 *s = *newSize
126
127 return err
128}
129
130func (d *Date) UnmarshalYAML(y *yaml.Node) error {
131 switch y.ShortTag() {
132 case "!!str":
133 val := strings.TrimSuffix(strings.TrimPrefix(y.Value, `"`), `"`)
134 t, err := time.Parse(`2006-01-02`, val)
135 if err != nil {
136 return err
137 }
138 d.Time = t
139 return nil
140 case "!!timestamp":
141 t, err := time.Parse(`2006-01-02`, y.Value)
142 if err != nil {
143 return err
144 }
145 d.Time = t
146 return nil
147 }
148
149 return fmt.Errorf("dates need to be in the format YYYY-MM-DD")
150}
151
152func (d Date) MarshalYAML() (interface{}, error) {
153 if d.Time.IsZero() {
154 return nil, nil
155 }
156 return d.Time.Format(`2006-01-02`), nil
157}
158
159func (c Color) MarshalYAML() (interface{}, error) {
160 return fmt.Sprintf(`#%02X%02X%02X`, c.R, c.G, c.B), nil
161}
162
163func (c *Color) UnmarshalYAML(y *yaml.Node) error {
164 if y.ShortTag() != "!!str" {
165 return fmt.Errorf("invalid color format, expected a string")
166 }
167
168 r, g, b, err := rgbFromString(y.Value)
169 if err != nil {
170 return err
171 }
172
173 c.R, c.G, c.B = r, g, b
174 c.A = 255
175 return nil
176}
177
178var _ yaml.Unmarshaler = (*Flip)(nil)
179var _ yaml.Marshaler = (*Polygon)(nil)
180var _ yaml.Unmarshaler = (*Polygon)(nil)
181var _ yaml.Marshaler = (*Size)(nil)
182var _ yaml.Unmarshaler = (*Size)(nil)
183var _ yaml.Marshaler = (*AnnotatedText)(nil)
184var _ yaml.Unmarshaler = (*AnnotatedText)(nil)
185var _ yaml.Marshaler = (*Date)(nil)
186var _ yaml.Unmarshaler = (*Date)(nil)
187var _ yaml.Marshaler = (*Color)(nil)
188var _ yaml.Unmarshaler = (*Color)(nil)