game.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. // Package game defines the provider-agnostic free-game offer type shared by
  2. // all store clients (epic, steam, ...).
  3. package game
  4. import (
  5. "context"
  6. "time"
  7. )
  8. // Game describes one free game offer, independent of the store it came from.
  9. type Game struct {
  10. Title string `json:"title"`
  11. ID string `json:"id"` // store-stable ID (epic offer id / steam appid)
  12. Slug string `json:"slug"` // store page slug or empty
  13. URL string `json:"url"` // full store page URL
  14. Store string `json:"store"`
  15. Kind string `json:"kind,omitempty"` // e.g. "free-now", "upcoming", "free-to-keep", "free-weekend"
  16. Description string `json:"description,omitempty"`
  17. Seller string `json:"seller,omitempty"`
  18. StartDate time.Time `json:"start_date,omitempty"`
  19. EndDate time.Time `json:"end_date,omitempty"` // end of the free period, zero = unknown
  20. PriceFmt string `json:"price_formatted,omitempty"` // original price, formatted
  21. FinalPriceFmt string `json:"final_price_formatted,omitempty"` // discounted price, formatted (deals only)
  22. DiscountPct int `json:"discount_pct,omitempty"` // e.g. 90 = 90 % off (deals only)
  23. }
  24. // Provider is implemented by every store client.
  25. type Provider interface {
  26. // Name returns the store identifier, e.g. "epic" or "steam".
  27. Name() string
  28. // GetFreeGames returns the games that are currently free.
  29. GetFreeGames(ctx context.Context) ([]Game, error)
  30. }
  31. // UpcomingProvider is implemented by stores that announce future giveaways.
  32. // Providers without it are skipped when upcoming offers are requested.
  33. type UpcomingProvider interface {
  34. // GetUpcomingGames returns announced games that will become free.
  35. GetUpcomingGames(ctx context.Context) ([]Game, error)
  36. }
  37. // DealProvider is implemented by stores that expose discounted offers.
  38. // Providers without it are skipped when deals are requested.
  39. type DealProvider interface {
  40. // GetDeals returns currently discounted games (free ones included).
  41. GetDeals(ctx context.Context) ([]Game, error)
  42. }