diff --git a/atom.go b/atom.go index 581b61d..e1ee5ef 100644 --- a/atom.go +++ b/atom.go @@ -89,13 +89,16 @@ type Atom struct { func newAtomEntry(i *Item) *AtomEntry { id := i.Id - + link := i.Link + if link == nil { + link = &Link{} + } if len(id) == 0 { // if there's no id set, try to create one, either from data or just a uuid - if len(i.Link.Href) > 0 && (!i.Created.IsZero() || !i.Updated.IsZero()) { + if len(link.Href) > 0 && (!i.Created.IsZero() || !i.Updated.IsZero()) { dateStr := anyTimeFormat("2006-01-02", i.Updated, i.Created) - host, path := i.Link.Href, "/invalid.html" - if url, err := url.Parse(i.Link.Href); err == nil { + host, path := link.Href, "/invalid.html" + if url, err := url.Parse(link.Href); err == nil { host, path = url.Host, url.Path } id = fmt.Sprintf("tag:%s,%s:%s", host, dateStr, path) @@ -108,13 +111,13 @@ func newAtomEntry(i *Item) *AtomEntry { name, email = i.Author.Name, i.Author.Email } - link_rel := i.Link.Rel + link_rel := link.Rel if link_rel == "" { link_rel = "alternate" } x := &AtomEntry{ Title: i.Title, - Links: []AtomLink{{Href: i.Link.Href, Rel: link_rel, Type: i.Link.Type}}, + Links: []AtomLink{{Href: link.Href, Rel: link_rel, Type: link.Type}}, Id: id, Updated: anyTimeFormat(time.RFC3339, i.Updated, i.Created), } @@ -145,12 +148,16 @@ func newAtomEntry(i *Item) *AtomEntry { // create a new AtomFeed with a generic Feed struct's data func (a *Atom) AtomFeed() *AtomFeed { updated := anyTimeFormat(time.RFC3339, a.Updated, a.Created) + link := a.Link + if link == nil { + link = &Link{} + } feed := &AtomFeed{ Xmlns: ns, Title: a.Title, - Link: &AtomLink{Href: a.Link.Href, Rel: a.Link.Rel}, + Link: &AtomLink{Href: link.Href, Rel: link.Rel}, Subtitle: a.Description, - Id: a.Link.Href, + Id: link.Href, Updated: updated, Rights: a.Copyright, } diff --git a/feed_test.go b/feed_test.go index 861366a..9aac7d3 100644 --- a/feed_test.go +++ b/feed_test.go @@ -541,6 +541,58 @@ func TestFeedSorted(t *testing.T) { } } +func TestFeedNil(t *testing.T) { + now, err := time.Parse(time.RFC3339, "2013-01-16T21:52:35-05:00") + if err != nil { + t.Error(err) + } + tz := time.FixedZone("EST", -5*60*60) + now = now.In(tz) + + feed := &Feed{ + Title: "jmoiron.net blog", + Link: nil, + Description: "discussion about tech, footie, photos", + Author: nil, + Created: now, + Copyright: "This work is copyright © Benjamin Button", + } + + feed.Items = []*Item{ + { + Title: "Limiting Concurrency in Go", + Link: nil, + Description: "A discussion on controlled parallelism in golang", + Author: nil, + Created: now, + Content: `
Go's goroutines make it easy to make embarrassingly parallel programs, but in many "real world" cases resources can be limited and attempting to do everything at once can exhaust your access to them.
`, + }} + + if _, err := feed.ToAtom(); err != nil { + t.Errorf("unexpected error encoding Atom: %v", err) + } + var buf bytes.Buffer + if err := feed.WriteAtom(&buf); err != nil { + t.Errorf("unexpected error writing Atom: %v", err) + } + + if _, err := feed.ToRss(); err != nil { + t.Errorf("unexpected error encoding RSS: %v", err) + } + buf.Reset() + if err := feed.WriteRss(&buf); err != nil { + t.Errorf("unexpected error writing RSS: %v", err) + } + + if _, err := feed.ToJSON(); err != nil { + t.Errorf("unexpected error encoding JSON: %v", err) + } + buf.Reset() + if err := feed.WriteJSON(&buf); err != nil { + t.Errorf("unexpected error writing JSON: %v", err) + } +} + var jsonOutputHub = `{ "version": "https://jsonfeed.org/version/1.1", "title": "feed title", diff --git a/rss.go b/rss.go index 232527e..7971bfc 100644 --- a/rss.go +++ b/rss.go @@ -144,9 +144,13 @@ func (r *Rss) RssFeed() *RssFeed { image = &RssImage{Url: r.Image.Url, Title: r.Image.Title, Link: r.Image.Link, Width: r.Image.Width, Height: r.Image.Height} } + var href string + if r.Link != nil { + href = r.Link.Href + } channel := &RssFeed{ Title: r.Title, - Link: r.Link.Href, + Link: href, Description: r.Description, ManagingEditor: author, PubDate: pub,