diff --git a/atom.go b/atom.go index 55d0532..70d90ed 100644 --- a/atom.go +++ b/atom.go @@ -1,6 +1,7 @@ package atom import ( + "encoding/xml" "fmt" "html" "mime" @@ -11,6 +12,29 @@ import ( "golang.org/x/text/language" ) +type Countable interface { + *xml.Attr | *Person | *Category | *Link | *ExtensionElement | *Entry +} + +func addToSlice[C Countable](slice []C, countable C) { + if slice == nil { + slice = make([]C, 1) + slice[0] = countable + } else { + slice = append(slice, countable) + } +} + +func deleteFromSlice[C Countable](slice []C, id int) error { + length := len(slice) + if id > length { + return fmt.Errorf("id %v out of range %v", id, length) + } + + slice = append(slice[:id], slice[id+1:]...) + return nil +} + // isValidIRI checks whether an IRI is valid or not. It returns a bool. // https://www.w3.org/2011/04/XMLSchema/TypeLibrary-IRI-RFC3987.xsd func isValidIRI(iri string) bool { diff --git a/commonAttributes.go b/commonAttributes.go index 875eea7..e8d5d2b 100644 --- a/commonAttributes.go +++ b/commonAttributes.go @@ -19,23 +19,15 @@ func newCommonAttributes() *CommonAttributes { // AddAttribute adds the attribute to the CommonAttributes. func (c *CommonAttributes) AddAttribute(name, value string) { - if c.UndefinedAttributes == nil { - c.UndefinedAttributes = make([]*xml.Attr, 1) - c.UndefinedAttributes[0] = &xml.Attr{Name: xml.Name{Local: name}, Value: value} - } else { - c.UndefinedAttributes = append(c.UndefinedAttributes, &xml.Attr{Name: xml.Name{Local: name}, Value: value}) - } + addToSlice(c.UndefinedAttributes, &xml.Attr{Name: xml.Name{Local: name}, Value: value}) } // DeleteAttribute deletes the attribute from the CommonAttributes. It return an // error. func (c *CommonAttributes) DeleteAttribute(id int) error { - length := len(c.UndefinedAttributes) - if id > length { - return fmt.Errorf("error deleting undefined attribute from common attributes %v: id %v out of range %v", c, id, length) + if err := deleteFromSlice(c.UndefinedAttributes, id); err != nil { + return fmt.Errorf("error deleting undefined attribute %v from common attributes %v: %v", id, c, err) } - - c.UndefinedAttributes = append(c.UndefinedAttributes[:id], c.UndefinedAttributes[id+1:]...) return nil } diff --git a/entry.go b/entry.go index 6b74f5f..b2fe95e 100644 --- a/entry.go +++ b/entry.go @@ -68,120 +68,80 @@ func NewEntry(title string) *Entry { // AddAuthor adds the Person as an author to the Entry. func (e *Entry) AddAuthor(p *Person) { - if e.Authors == nil { - e.Authors = make([]*Person, 1) - e.Authors[0] = p - } else { - e.Authors = append(e.Authors, p) - } - + addToSlice(e.Authors, p) e.Updated = NewDate(time.Now()) } // DeleteAuthor deletes the Person from the Entry. It return an error. func (e *Entry) DeleteAuthor(id int) error { - length := len(e.Authors) - if id > length { - return fmt.Errorf("error deleting author from entry %v: id %v out of range %v", e.ID.URI, id, length) + if err := deleteFromSlice(e.Authors, id); err != nil { + return fmt.Errorf("error deleting author %v from entry %v: %v", id, e.ID.URI, err) } - e.Authors = append(e.Authors[:id], e.Authors[id+1:]...) e.Updated = NewDate(time.Now()) return nil } // AddCategory adds the Category to the Entry. func (e *Entry) AddCategory(c *Category) { - if e.Categories == nil { - e.Categories = make([]*Category, 1) - e.Categories[0] = c - } else { - e.Categories = append(e.Categories, c) - } - + addToSlice(e.Categories, c) e.Updated = NewDate(time.Now()) } // DeleteCategory deletes the Category from the Entry. It return an error. func (e *Entry) DeleteCategory(id int) error { - length := len(e.Categories) - if id > length { - return fmt.Errorf("error deleting category from entry %v: id %v out of range %v", e.ID.URI, id, length) + if err := deleteFromSlice(e.Categories, id); err != nil { + return fmt.Errorf("error deleting category %v from entry %v: %v", id, e.ID.URI, err) } - e.Categories = append(e.Categories[:id], e.Categories[id+1:]...) e.Updated = NewDate(time.Now()) return nil } // AddContributor adds the Person as a contributor to the Entry. func (e *Entry) AddContributor(c *Person) { - if e.Contributors == nil { - e.Contributors = make([]*Person, 1) - e.Contributors[0] = c - } else { - e.Contributors = append(e.Contributors, c) - } - + addToSlice(e.Contributors, c) e.Updated = NewDate(time.Now()) } // DeleteContributor deletes the Person from the Entry. It return an error. func (e *Entry) DeleteContributor(id int) error { - length := len(e.Contributors) - if id > length { - return fmt.Errorf("error deleting contributor from entry %v: id %v out of range %v", e.ID.URI, id, length) + if err := deleteFromSlice(e.Contributors, id); err != nil { + return fmt.Errorf("error deleting contributor %v from entry %v: %v", id, e.ID.URI, err) } - e.Contributors = append(e.Contributors[:id], e.Contributors[id+1:]...) e.Updated = NewDate(time.Now()) return nil } // AddLink adds the Link to the Entry. func (e *Entry) AddLink(l *Link) { - if e.Links == nil { - e.Links = make([]*Link, 1) - e.Links[0] = l - } else { - e.Links = append(e.Links, l) - } - + addToSlice(e.Links, l) e.Updated = NewDate(time.Now()) } // DeleteLink deletes the Link from the Entry. It return an error. func (e *Entry) DeleteLink(id int) error { - length := len(e.Links) - if id > length { - return fmt.Errorf("error deleting link from entry %v: id %v out of range %v", e.ID.URI, id, length) + if err := deleteFromSlice(e.Links, id); err != nil { + return fmt.Errorf("error deleting link %v from entry %v: %v", id, e.ID.URI, err) } - e.Links = append(e.Links[:id], e.Links[id+1:]...) e.Updated = NewDate(time.Now()) return nil } // AddExtension adds the ExtensionElement to the Entry. func (e *Entry) AddExtension(x *ExtensionElement) { - if e.Extensions == nil { - e.Extensions = make([]*ExtensionElement, 1) - e.Extensions[0] = x - } else { - e.Extensions = append(e.Extensions, x) - } - + addToSlice(e.Extensions, x) e.Updated = NewDate(time.Now()) } // DeleteExtension deletes the Extension from the Entry. It return an error. func (e *Entry) DeleteExtension(id int) error { - length := len(e.Extensions) - if id > length { - return fmt.Errorf("error deleting extension from entry %v: id %v out of range %v", e.ID.URI, id, length) + if err := deleteFromSlice(e.Extensions, id); err != nil { + return fmt.Errorf("error deleting extension %v from entry %v: %v", id, e.ID.URI, err) } - e.Extensions = append(e.Extensions[:id], e.Extensions[id+1:]...) e.Updated = NewDate(time.Now()) return nil } diff --git a/feed.go b/feed.go index 1ba637d..b496192 100644 --- a/feed.go +++ b/feed.go @@ -37,144 +37,96 @@ func NewFeed(title string) *Feed { // AddAuthor adds the Person as an author to the Feed. func (f *Feed) AddAuthor(p *Person) { - if f.Authors == nil { - f.Authors = make([]*Person, 1) - f.Authors[0] = p - } else { - f.Authors = append(f.Authors, p) - } - + addToSlice(f.Authors, p) f.Updated = NewDate(time.Now()) } // DeleteAuthor deletes the Person from the Feed. It return an error. func (f *Feed) DeleteAuthor(id int) error { - length := len(f.Authors) - if id > length { - return fmt.Errorf("error deleting author from feed %v: id %v out of range %v", f.ID.URI, id, length) + if err := deleteFromSlice(f.Authors, id); err != nil { + return fmt.Errorf("error deleting author %v from entry %v: %v", id, f.ID.URI, err) } - f.Authors = append(f.Authors[:id], f.Authors[id+1:]...) f.Updated = NewDate(time.Now()) return nil } // AddCategory adds the Category to the Feed. func (f *Feed) AddCategory(c *Category) { - if f.Categories == nil { - f.Categories = make([]*Category, 1) - f.Categories[0] = c - } else { - f.Categories = append(f.Categories, c) - } - + addToSlice(f.Categories, c) f.Updated = NewDate(time.Now()) } // DeleteCategory deletes the Category from the Feed. It return an error. func (f *Feed) DeleteCategory(id int) error { - length := len(f.Categories) - if id > length { - return fmt.Errorf("error deleting category from feed %v: id %v out of range %v", f.ID.URI, id, length) + if err := deleteFromSlice(f.Categories, id); err != nil { + return fmt.Errorf("error deleting category %v from entry %v: %v", id, f.ID.URI, err) } - f.Categories = append(f.Categories[:id], f.Categories[id+1:]...) f.Updated = NewDate(time.Now()) return nil } // AddContributor adds the Person as a contributor to the Feed. func (f *Feed) AddContributor(c *Person) { - if f.Contributors == nil { - f.Contributors = make([]*Person, 1) - f.Contributors[0] = c - } else { - f.Contributors = append(f.Contributors, c) - } - + addToSlice(f.Contributors, c) f.Updated = NewDate(time.Now()) } // DeleteContributor deletes the Person from the Feed. It return an error. func (f *Feed) DeleteContributor(id int) error { - length := len(f.Contributors) - if id > length { - return fmt.Errorf("error deleting contributor from feed %v: id %v out of range %v", f.ID.URI, id, length) + if err := deleteFromSlice(f.Contributors, id); err != nil { + return fmt.Errorf("error deleting contributor %v from entry %v: %v", id, f.ID.URI, err) } - f.Contributors = append(f.Contributors[:id], f.Contributors[id+1:]...) f.Updated = NewDate(time.Now()) return nil } // AddLink adds the Link to the Feed. There should be one Link with Rel "self". func (f *Feed) AddLink(l *Link) { - if f.Links == nil { - f.Links = make([]*Link, 1) - f.Links[0] = l - } else { - f.Links = append(f.Links, l) - } - + addToSlice(f.Links, l) f.Updated = NewDate(time.Now()) } // DeleteLink deletes the Link from the Feed. It return an error. func (f *Feed) DeleteLink(id int) error { - length := len(f.Links) - if id > length { - return fmt.Errorf("error deleting link from feed %v: id %v out of range %v", f.ID.URI, id, length) + if err := deleteFromSlice(f.Links, id); err != nil { + return fmt.Errorf("error deleting link %v from entry %v: %v", id, f.ID.URI, err) } - f.Links = append(f.Links[:id], f.Links[id+1:]...) f.Updated = NewDate(time.Now()) return nil } // AddExtension adds the Extension to the Feed. func (f *Feed) AddExtension(e *ExtensionElement) { - if f.Extensions == nil { - f.Extensions = make([]*ExtensionElement, 1) - f.Extensions[0] = e - } else { - f.Extensions = append(f.Extensions, e) - } - + addToSlice(f.Extensions, e) f.Updated = NewDate(time.Now()) } // DeleteExtension deletes the Extension from the Feed. It return an error. func (f *Feed) DeleteExtension(id int) error { - length := len(f.Extensions) - if id > length { - return fmt.Errorf("error deleting extension from feed %v: id %v out of range %v", f.ID.URI, id, length) + if err := deleteFromSlice(f.Extensions, id); err != nil { + return fmt.Errorf("error deleting extension %v from entry %v: %v", id, f.ID.URI, err) } - f.Extensions = append(f.Extensions[:id], f.Extensions[id+1:]...) f.Updated = NewDate(time.Now()) return nil } // AddEntry adds the Entry to the Feed. func (f *Feed) AddEntry(e *Entry) { - if f.Entries == nil { - f.Entries = make([]*Entry, 1) - f.Entries[0] = e - } else { - f.Entries = append(f.Entries, e) - } - + addToSlice(f.Entries, e) f.Updated = NewDate(time.Now()) } // DeleteEntry deletes the Entry from the Feed. It return an error. func (f *Feed) DeleteEntry(id int) error { - length := len(f.Entries) - if id > length { - return fmt.Errorf("error deleting entry from feed %v: id %v out of range %v", f.ID.URI, id, length) + if err := deleteFromSlice(f.Entries, id); err != nil { + return fmt.Errorf("error deleting entry %v from entry %v: %v", id, f.ID.URI, err) } - f.Entries = append(f.Entries[:id], f.Entries[id+1:]...) f.Updated = NewDate(time.Now()) return nil } diff --git a/person.go b/person.go index 2864681..5505698 100644 --- a/person.go +++ b/person.go @@ -23,22 +23,14 @@ func NewPerson(name string) *Person { // AddExtension adds the Extension to the Person. func (p *Person) AddExtension(e *ExtensionElement) { - if p.Extensions == nil { - p.Extensions = make([]*ExtensionElement, 1) - p.Extensions[0] = e - } else { - p.Extensions = append(p.Extensions, e) - } + addToSlice(p.Extensions, e) } // DeleteExtension deletes the Extension from the Person. It return an error. func (p *Person) DeleteExtension(id int) error { - length := len(p.Extensions) - if id > length { - return fmt.Errorf("error deleting extension from person %v: id %v out of range %v", p, id, length) + if err := deleteFromSlice(p.Extensions, id); err != nil { + return fmt.Errorf("error deleting extension %v from person %v: %v", id, p, err) } - - p.Extensions = append(p.Extensions[:id], p.Extensions[id+1:]...) return nil } diff --git a/source.go b/source.go index 3af7601..4f175b9 100644 --- a/source.go +++ b/source.go @@ -30,106 +30,66 @@ func NewSource() *Source { // AddAuthor adds the Person as an author to the Source. func (s *Source) AddAuthor(p *Person) { - if s.Authors == nil { - s.Authors = make([]*Person, 1) - s.Authors[0] = p - } else { - s.Authors = append(s.Authors, p) - } + addToSlice(s.Authors, p) } // DeleteAuthor deletes the Person from the Source. It return an error. func (s *Source) DeleteAuthor(id int) error { - length := len(s.Authors) - if id > length { - return fmt.Errorf("error deleting author from source %v: id %v out of range %v", s, id, length) + if err := deleteFromSlice(s.Authors, id); err != nil { + return fmt.Errorf("error deleting author %v from source %v: %v", id, s, err) } - - s.Authors = append(s.Authors[:id], s.Authors[id+1:]...) return nil } // AddCategory adds the Category to the Source. func (s *Source) AddCategory(c *Category) { - if s.Categories == nil { - s.Categories = make([]*Category, 1) - s.Categories[0] = c - } else { - s.Categories = append(s.Categories, c) - } + addToSlice(s.Categories, c) } // DeleteCategory deletes the Category from the Source. It return an error. func (s *Source) DeleteCategory(id int) error { - length := len(s.Categories) - if id > length { - return fmt.Errorf("error deleting category from source %v: id %v out of range %v", s, id, length) + if err := deleteFromSlice(s.Categories, id); err != nil { + return fmt.Errorf("error deleting category %v from source %v: %v", id, s, err) } - - s.Categories = append(s.Categories[:id], s.Categories[id+1:]...) return nil } // AddContributor adds the Person as a contributor to the Source. func (s *Source) AddContributor(c *Person) { - if s.Contributors == nil { - s.Contributors = make([]*Person, 1) - s.Contributors[0] = c - } else { - s.Contributors = append(s.Contributors, c) - } + addToSlice(s.Contributors, c) } // DeleteContributor deletes the Person from the Source. It return an error. func (s *Source) DeleteContributor(id int) error { - length := len(s.Contributors) - if id > length { - return fmt.Errorf("error deleting contributor from source %v: id %v out of range %v", s, id, length) + if err := deleteFromSlice(s.Contributors, id); err != nil { + return fmt.Errorf("error deleting contributor %v from source %v: %v", id, s, err) } - - s.Contributors = append(s.Contributors[:id], s.Contributors[id+1:]...) return nil } // AddLink adds the Link to the Source. func (s *Source) AddLink(l *Link) { - if s.Links == nil { - s.Links = make([]*Link, 1) - s.Links[0] = l - } else { - s.Links = append(s.Links, l) - } + addToSlice(s.Links, l) } // DeleteLink deletes the Link from the Source. It return an error. func (s *Source) DeleteLink(id int) error { - length := len(s.Links) - if id > length { - return fmt.Errorf("error deleting link from source %v: id %v out of range %v", s, id, length) + if err := deleteFromSlice(s.Links, id); err != nil { + return fmt.Errorf("error deleting link %v from source %v: %v", id, s, err) } - - s.Links = append(s.Links[:id], s.Links[id+1:]...) return nil } // AddExtension adds the ExtensionElement to the Source. func (s *Source) AddExtension(e *ExtensionElement) { - if s.Extensions == nil { - s.Extensions = make([]*ExtensionElement, 1) - s.Extensions[0] = e - } else { - s.Extensions = append(s.Extensions, e) - } + addToSlice(s.Extensions, e) } // DeleteExtension deletes the Extension from the Source. It return an error. func (s *Source) DeleteExtension(id int) error { - length := len(s.Extensions) - if id > length { - return fmt.Errorf("error deleting extension from source %v: id %v out of range %v", s, id, length) + if err := deleteFromSlice(s.Extensions, id); err != nil { + return fmt.Errorf("error deleting extension %v from source %v: %v", id, s, err) } - - s.Extensions = append(s.Extensions[:id], s.Extensions[id+1:]...) return nil }