atom/link.go
Jason Streifling d11b229691 No more undefined content in link and category
It seems that undefined content is only mentioned in RFC4287 because
link and category are elements and those usually need some content.
2024-10-17 18:57:43 +02:00

88 lines
2.2 KiB
Go

package atom
import (
"errors"
"fmt"
"strings"
)
type Link struct {
*CommonAttributes
Title string `xml:"title,attr,omitempty"`
Href IRI `xml:"href,attr"`
Rel string `xml:"rel,attr,omitempty"`
Type MediaType `xml:"type,attr,omitempty"`
HrefLang LanguageTag `xml:"hreflang,attr,omitempty"`
Length uint `xml:"length,attr,omitempty"`
}
// NewLink creates a new Link. It returns a *Link and an error.
func NewLink(href, content string) *Link {
return &Link{Href: IRI(href)}
}
// Check checks the Link for incompatibilities with RFC4287. It returns an
// error.
func (l *Link) Check() error {
if l.Href == "" {
return errors.New("href attribute of link empty")
} else {
if !isValidIRI(l.Href) {
return fmt.Errorf("href attribute %v of link not correctly formatted", l.Href)
}
}
if l.Rel != "" {
if strings.Contains(l.Rel, ":") && !isValidIRI(IRI(l.Rel)) {
return fmt.Errorf("rel attribute %v of link %v not correctly formatted", l.Rel, l.Href)
}
}
if l.Type != "" {
if !isValidMediaType(string(l.Type)) {
return fmt.Errorf("type attribute %v of link %v invalid media type", l.Type, l.Href)
}
}
if l.HrefLang != "" {
if !isValidLanguageTag(l.HrefLang) {
return fmt.Errorf("hreflang attribute %v of link %v invalid language tag", l.Type, l.HrefLang)
}
}
return nil
}
// hasAlternateDuplicateLinks checks whether multiple Links with Rel
// "alternate" also have Type and HrefLang in common. It returns a bool.
// atom:feed/entry elements MUST NOT contain more than one atom:link element
// with a rel attribute value of "alternate" that has the same combination of
// type and hreflang attribute values.
func hasAlternateDuplicateLinks(l []*Link) bool {
linkMap := make(map[string]bool)
for _, link := range l {
if link.Rel == "alternate" {
key := fmt.Sprint(link.Type, "|", link.HrefLang)
if linkMap[key] {
return true
}
linkMap[key] = true
}
}
return false
}
// alternateRelExists checks whether multiple Links with Rel "alternate" exist.
// It returns a bool.
func alternateRelExists(l []*Link) bool {
for _, link := range l {
if link.Rel == "alternate" {
return true
}
}
return false
}