A tool for archiving & converting scans of postcards, and information about them.
at main 188 lines 3.9 kB view raw
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)