Mercurial > gemma
view pkg/models/common.go @ 4904:53d929f658f3 fairway-marks-import
Separate code common to all types of fairway mark imports
Currently the only implemented type of fairway marks is BCNLAT.
author | Tom Gottfried <tom@intevation.de> |
---|---|
date | Thu, 06 Feb 2020 19:09:14 +0100 |
parents | 4847ac70103a |
children | d19fdf3d2099 |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2018 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package models import ( "database/sql/driver" "encoding/json" "errors" "fmt" "strings" "time" "gemma.intevation.de/gemma/pkg/common" ) var ( errNoString = errors.New("not a string") errNoByteSlice = errors.New("not a byte slice") ) // WGS84 is the EPSG of the World Geodetic System 1984. const WGS84 = 4326 type ( Date struct{ time.Time } Time struct{ time.Time } // Country is a valid country 2 letter code. Country string // UniqueCountries is a list of unique countries. UniqueCountries []Country ) func (d Date) MarshalJSON() ([]byte, error) { return json.Marshal(d.Format(common.DateFormat)) } func (d *Date) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } d2, err := time.Parse(common.DateFormat, s) if err == nil { *d = Date{d2} } return err } func (t Time) MarshalJSON() ([]byte, error) { return json.Marshal(t.Format(common.TimeFormat)) } func (t *Time) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } t2, err := time.Parse(common.TimeFormat, s) if err == nil { *t = Time{t2} } return err } var ( validCountries = []string{ "AT", "BG", "DE", "HU", "HR", "MD", "RO", "RS", "SK", "UA", } ) // Valid checks if the given country is a known one. func (c Country) Valid() bool { for _, v := range validCountries { if string(c) == v { return true } } return false } // UnmarshalJSON ensures that the given string forms a valid // two letter country code. func (c *Country) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } u := strings.ToUpper(s) for _, v := range validCountries { if v == u { *c = Country(v) return nil } } return fmt.Errorf("'%s' is not a valid country", s) } // Value implements the driver.Valuer interface. func (c Country) Value() (driver.Value, error) { return string(c), nil } // Scan implements the sql.Scanner interfaces. func (c *Country) Scan(src interface{}) (err error) { if s, ok := src.(string); ok { *c = Country(s) } else { err = errNoString } return } func (uc *UniqueCountries) UnmarshalJSON(data []byte) error { var countries []Country if err := json.Unmarshal(data, &countries); err != nil { return err } unique := map[Country]struct{}{} for _, c := range countries { if _, found := unique[c]; found { return fmt.Errorf("country '%s' is not unique", string(c)) } unique[c] = struct{}{} } *uc = countries return nil } func (uc UniqueCountries) String() string { var b strings.Builder for i, c := range uc { if i > 0 { b.WriteString(", ") } b.WriteString(string(c)) } return b.String() }