package main import ( "fmt" "strings" ) type linkParseError struct { msg string } func (e linkParseError) Error() string { return "link parse error: " + e.msg } type link struct { Title string URL string Rel string } func (l link) String() string { return fmt.Sprintf("Title: %s, URL: %s, Rel: %s", l.Title, l.URL, l.Rel) } type links []link func (l *links) Set(value string) error { linkAttributes := strings.Split(value, ",") lenLinkAttributes := len(linkAttributes) if lenLinkAttributes != 2 && lenLinkAttributes != 3 { return linkParseError{msg: fmt.Sprintf("unexpected number of attributes found %s, want 2 or 3, got %d", value, lenLinkAttributes)} } var thisLink link for _, attr := range linkAttributes { split := strings.Split(attr, "=") switch strings.ToLower(split[0]) { case "title": thisLink.Title = split[1] case "url": thisLink.URL = split[1] case "rel": thisLink.Rel = split[1] } } if thisLink.Title == "" { return linkParseError{msg: fmt.Sprintf("the title attribute is missing from %s", value)} } if thisLink.URL == "" { return linkParseError{msg: fmt.Sprintf("the URL attribute is missing from %s", value)} } *l = append(*l, thisLink) return nil } func (l *links) String() string { if len(*l) == 0 { return "" } var builder strings.Builder for _, link := range *l { fmt.Fprintln(&builder, link) } return builder.String() }