type EpisodeContainer interface {
// Returns true if this EpisodeContainer is equivalent or a superset of the given EpisodeContainer
ContainsEpisodes(EpisodeContainer) bool
+ // Returns a channel meant for iterating with for/range.
+ // Sends all contained episodes in order.
+ Episodes() chan Episode
}
type Formatter interface {
return scale(ep.Number)
}
+func (ep *Episode) Episodes() chan Episode {
+ ch := make(chan Episode, 1)
+ if ep != nil {
+ ch <- *ep
+ }
+ close(ch)
+ return ch
+}
+
// Returns true if ec is an Episode and is identical to this episode,
// or if ec is a single episode EpisodeRange / EpisodeList that
// contain only this episode.
return strings.Join(parts, ",")
}
+func (el EpisodeList) Infinite() bool {
+ for i := range el {
+ if el[i].Infinite() {
+ return true
+ }
+ }
+ return false
+}
+
+// Returns a channel that can be used to iterate using for/range.
+//
+// If the EpisodeList is infinite, then the channel is also infinite.
+// The caller is allowed to close the channel in such case.
+//
+// NOTE: Not thread safe.
+func (el EpisodeList) Episodes() chan Episode {
+ ch := make(chan Episode, 1)
+
+ go func() {
+ abort := false
+
+ if el.Infinite() {
+ defer func() { recover(); abort = true }()
+ } else {
+ defer close(ch)
+ }
+
+ for _, er := range el {
+ for ep := range er.Episodes() {
+ ch <- ep
+
+ if abort {
+ return
+ }
+ }
+ }
+ }()
+ return ch
+}
+
// Returns true if any of the contained EpisodeRanges contain the
// given EpisodeContainer.
func (el EpisodeList) ContainsEpisodes(ec EpisodeContainer) bool {