9 type EpisodeCount struct {
18 type EpisodeList []*EpisodeRange
20 func EpisodeToList(ep *Episode) EpisodeList {
21 return RangesToList(EpisodeToRange(ep))
24 func RangesToList(ranges ...*EpisodeRange) EpisodeList {
25 return EpisodeList(ranges)
28 func ContainerToList(ec EpisodeContainer) EpisodeList {
29 switch v := ec.(type) {
31 return EpisodeToList(v)
33 return RangesToList(v)
37 panic("unimplemented")
41 // Converts the EpisodeList into the AniDB API list format.
42 func (el EpisodeList) String() string {
43 scales := map[EpisodeType]int{}
45 for _, er := range el {
51 if s > scales[er.Type] {
56 parts := make([]string, len(el))
57 for i, er := range el {
58 parts[i] = er.Format(scales[er.Type])
61 return strings.Join(parts, ",")
64 // Formats the list according to the number of digits of
65 // the count for its type, given in the EpisodeCount.
66 func (el EpisodeList) FormatLog(ec EpisodeCount) string {
67 parts := make([]string, len(el))
68 for i, er := range el {
70 case EpisodeTypeRegular:
71 parts[i] = er.FormatLog(ec.RegularCount)
72 case EpisodeTypeSpecial:
73 parts[i] = er.FormatLog(ec.SpecialCount)
74 case EpisodeTypeCredits:
75 parts[i] = er.FormatLog(ec.CreditsCount)
76 case EpisodeTypeOther:
77 parts[i] = er.FormatLog(ec.OtherCount)
78 case EpisodeTypeTrailer:
79 parts[i] = er.FormatLog(ec.TrailerCount)
80 case EpisodeTypeParody:
81 parts[i] = er.FormatLog(ec.ParodyCount)
83 parts[i] = er.Format(er.scale())
87 return strings.Join(parts, ",")
90 func (el EpisodeList) Infinite() bool {
99 // Returns a channel that can be used to iterate using for/range.
101 // If the EpisodeList is infinite, then the channel is also infinite.
102 // The caller is allowed to close the channel in such case.
104 // NOTE: Not thread safe.
105 func (el EpisodeList) Episodes() chan Episode {
106 ch := make(chan Episode, 1)
112 defer func() { recover(); abort = true }()
117 for _, er := range el {
118 for ep := range er.Episodes() {
130 // Returns true if any of the contained EpisodeRanges contain the
131 // given EpisodeContainer.
132 func (el EpisodeList) ContainsEpisodes(ec EpisodeContainer) bool {
133 for _, i := range el {
134 if i != nil && i.ContainsEpisodes(ec) {
141 // Parses a string in the AniDB API list format and converts into
144 // ParseEpisodeList("01") <=> EpisodeList{ParseEpisodeRange("01")}
145 // ParseEpisodeList("S2-S3") <=> EpisodeList{ParseEpisodeRange("S2-S3")}
146 // ParseEpisodeList("T1,C1-C3") <=> EpisodeList{ParseEpisodeRange("T1"), ParseEpisodeRange("C1-C3")}
147 func ParseEpisodeList(s string) (el EpisodeList) {
148 parts := strings.Split(s, ",")
150 el = make(EpisodeList, len(parts))
151 for i := range parts {
152 el[i] = ParseEpisodeRange(parts[i])
158 // Returns a simplified version of the EpisodeList (removes nil ranges, merges mergeable ranges, sorts).
159 func (el EpisodeList) Simplify() EpisodeList {
160 nl := make(EpisodeList, 0, len(el))
163 for _, er := range el {
170 for n, changed := 0, true; changed; n++ {
172 used := map[int]bool{}
175 for i, a := range nl {
179 for j, b := range nl[i+1:] {
180 if c := a.Merge(b); c != nil {
191 panic(fmt.Sprintf("Too many iterations (%d) when simplifing %s!", n, el))
198 func (el EpisodeList) CountEpisodes() (ec EpisodeCount) {
199 for _, er := range el {
202 case EpisodeTypeRegular:
204 case EpisodeTypeSpecial:
206 case EpisodeTypeCredits:
208 case EpisodeTypeOther:
210 case EpisodeTypeTrailer:
212 case EpisodeTypeParody:
224 *c += er.End.Number - er.Start.Number
229 func (el EpisodeList) Len() int {
233 func (el EpisodeList) Less(i, j int) bool {
239 case el[i].Type < el[j].Type:
241 case el[i].Type > el[j].Type:
243 case el[i].Start.Number < el[j].Start.Number:
249 func (el EpisodeList) Swap(i, j int) {
250 el[i], el[j] = el[j], el[i]
253 func (el *EpisodeList) Add(ec EpisodeContainer) {
254 *el = append(*el, ContainerToList(ec)...)
258 func (el *EpisodeList) Sub(ec EpisodeContainer) {
259 el2 := make(EpisodeList, 0, len(*el)*2)
260 switch e, ok := ec.(canInfinite); {
267 for _, r := range *el {
268 el2 = append(el2, r.Split(&ep)[0])
274 for ep := range ec.Episodes() {
275 for _, r := range *el {
276 el2 = append(el2, r.Split(&ep)...)
281 *el = append(*el, el2.Simplify()...)