package acme import ( "encoding" "encoding/json" "errors" "net/mail" "strings" ) var errInvalidContact = errors.New("Ivalid contact") type Contact interface { encoding.TextMarshaler } type Contacts []Contact func (c *Contacts) UnmarshalJSON(b []byte) error { var tmp []string err := json.Unmarshal(b, &tmp) if err != nil { return err } *c = nil // invalidate old value for _, s := range tmp { switch { case strings.HasPrefix(s, "mailto:"): *c = append(*c, Mail(s[7:])) case strings.HasPrefix(s, "tel:"): *c = append(*c, Phone(s[4:])) default: return errInvalidContact } } return nil } type Mail string func (m Mail) MarshalText() ([]byte, error) { return []byte("mailto:" + m), nil } type Phone string func (ph Phone) MarshalText() ([]byte, error) { return []byte("tel:" + ph), nil } func NewContacts(email, phone string) (Contacts, error) { m, err := mail.ParseAddress(email) if err != nil { return nil, err } c := Contacts{Mail(m.Address)} if phone != "" { c = append(c, Phone(phone)) } return c, nil }