From b6d48bdc55ab772a7a4757d646fa278f259723de Mon Sep 17 00:00:00 2001 From: "Diogo Franco (Kovensky)" Date: Wed, 17 Jul 2013 17:55:16 -0300 Subject: [PATCH] misc: Make the iterator part of EpisodeContainer interface Also adds iterators to Episode (returns a single copy of itself) and to EpisodeList (returns the contents of the iterators of each sublist in sequence). --- misc/episode.go | 12 ++++++++++++ misc/episodelist.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/misc/episode.go b/misc/episode.go index c5d41a8..fee19d8 100644 --- a/misc/episode.go +++ b/misc/episode.go @@ -10,6 +10,9 @@ import ( 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 { @@ -95,6 +98,15 @@ func (ep *Episode) scale() int { 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. diff --git a/misc/episodelist.go b/misc/episodelist.go index 61be68b..10747a3 100644 --- a/misc/episodelist.go +++ b/misc/episodelist.go @@ -87,6 +87,46 @@ func (el EpisodeList) FormatLog(ec EpisodeCount) string { 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 { -- 2.44.0