package main import ( "context" "git.milar.in/milarin/anilist" "git.milar.in/milarin/channel" "git.milar.in/milarin/slices" ) type Pair[A, B any] struct { First A Second B } func GetAnimesToDownloadByAnimeID() (map[anilist.MediaID]*anilist.MediaList, error) { watchingAnimesChannel, err := GetCurrentlyWatchingAnimes() if err != nil { return nil, err } toMapFunc := func(entry *anilist.MediaList) (anilist.MediaID, *anilist.MediaList) { return entry.MediaID, entry } return channel.ToMap(watchingAnimesChannel, toMapFunc), nil } func GetCurrentlyWatchingAnimes() (<-chan *anilist.MediaList, error) { token, err := GetAnilistAccessToken() if err != nil { return nil, ErrAnimeListNotObtainable.Wrap(err, "access token acquisition failed") } media := slices.Map(AnimeStatus, func(status anilist.MediaListStatus) <-chan *anilist.MediaList { return anilist.NewApi(token).GetMediaList(context.Background(), anilist.MediaListQuery{ UserName: AnilistUsername, Type: anilist.MediaTypeAnime, Status: status, }, nil).Chan }) return channel.Merge(media...), nil } var ( animeByTitleCache = map[string]Pair[*anilist.Media, error]{} ) func SearchAnimeByTitle(title string) (anime *anilist.Media, err error) { // caching if cacheEntry, ok := animeByTitleCache[title]; ok { return cacheEntry.First, cacheEntry.Second } defer func() { animeByTitleCache[title] = Pair[*anilist.Media, error]{anime, err} }() token, err := GetAnilistAccessToken() if err != nil { return nil, err } anime = anilist.NewApi(token).GetMedia(context.Background(), anilist.MediaQuery{ Search: title, Type: anilist.MediaTypeAnime, }, nil).First() if anime == nil { return nil, ErrAnimeNotFound.New(title) } return anime, nil }