A tool for archiving & converting scans of postcards, and information about them.
at main 93 lines 2.4 kB view raw
1package types 2 3import ( 4 "fmt" 5) 6 7type SecretType struct { 8 Type string `json:"type" yaml:"type"` 9} 10 11type SecretPolygon struct { 12 Type string `json:"type" yaml:"type"` 13 Prehidden bool `json:"prehidden" yaml:"prehidden"` 14 Points []Point `json:"points" yaml:"points"` 15} 16 17type SecretBox struct { 18 Type string `json:"type" yaml:"type"` 19 Prehidden bool `json:"prehidden" yaml:"prehidden"` 20 Width float64 `json:"width" yaml:"width"` 21 Height float64 `json:"height" yaml:"height"` 22 Left float64 `json:"left" yaml:"left"` 23 Top float64 `json:"top" yaml:"top"` 24} 25 26// Allows polygons with type: box *and* type: polygon to be unmarshalled 27func (poly *Polygon) multiPolygonUnmarshaller(decode func(interface{}) error) error { 28 var typer SecretType 29 if err := decode(&typer); err != nil { 30 return fmt.Errorf("invalid secret definition") 31 } 32 33 switch typer.Type { 34 case "box": 35 var box SecretBox 36 if err := decode(&box); err != nil { 37 return fmt.Errorf("invalid box secret definition") 38 } 39 40 return box.intoPolygon(poly) 41 case "polygon": 42 var polygon SecretPolygon 43 if err := decode(&polygon); err != nil { 44 return fmt.Errorf("invalid polygon secret definition") 45 } 46 47 poly.Prehidden = polygon.Prehidden 48 poly.Points = polygon.Points 49 50 return nil 51 default: 52 return fmt.Errorf("unknown secret type: %s", typer.Type) 53 } 54} 55 56func (box SecretBox) intoPolygon(poly *Polygon) error { 57 poly.Prehidden = box.Prehidden 58 59 if outOfBounds(box.Width) { 60 return fmt.Errorf("width of box secret is larger than 100%% of the postcard") 61 } 62 if outOfBounds(box.Height) { 63 return fmt.Errorf("height of box secret is larger than 100%% of the postcard") 64 } 65 if outOfBounds(box.Left) { 66 return fmt.Errorf("left edge of box secret is outside the postcard") 67 } 68 if outOfBounds(box.Top) { 69 return fmt.Errorf("top edge of box secret is outside the postcard") 70 } 71 72 bottom := box.Top + box.Height 73 if outOfBounds(bottom) { 74 return fmt.Errorf("bottom edge of box secret is outside the postcard") 75 } 76 right := box.Left + box.Width 77 if outOfBounds(right) { 78 return fmt.Errorf("right edge of box secret is outside the postcard") 79 } 80 81 poly.Points = []Point{ 82 {X: box.Left, Y: box.Top}, 83 {X: right, Y: box.Top}, 84 {X: right, Y: bottom}, 85 {X: box.Left, Y: bottom}, 86 } 87 88 return nil 89} 90 91func outOfBounds(d float64) bool { 92 return d < 0.0 || d > 1.0 93}