]> git.lizzy.rs Git - go-anidb.git/commitdiff
misc: Make the iterator part of EpisodeContainer interface
authorDiogo Franco (Kovensky) <diogomfranco@gmail.com>
Wed, 17 Jul 2013 20:55:16 +0000 (17:55 -0300)
committerDiogo Franco (Kovensky) <diogomfranco@gmail.com>
Wed, 17 Jul 2013 20:55:16 +0000 (17:55 -0300)
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
misc/episodelist.go

index c5d41a88e3e566beaebbd9a8285947f08b64c596..fee19d8ba920647955fb121ca4c5d0da2f22a094 100644 (file)
@@ -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.
index 61be68bf0257717d16854bf415440ea053c5c452..10747a30e1f90a4503b37345132b13495dac0b49 100644 (file)
@@ -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 {