โ– humdrum codex / sportsball v0.1.0
license AGPL-3.0
1.6 KB raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package model

// Standings is a league table, fetched from ESPN's standings endpoint. Leagues
// split into one or more groups (soccer = groups, MLB = leagues, NBA/NHL/NFL =
// conferences); each group is an independent ranked table.
type Standings struct {
	League LeagueID
	Groups []StandingsGroup
}

// StandingsGroup is one ranked table within a league's standings.
type StandingsGroup struct {
	Name    string   // "Group A", "American League", "Eastern Conference", or ""
	Columns []string // stat column headers, parallel to each row's Values
	Rows    []StandingsRow
}

// StandingsRow is one team's line in a group, ranked by ESPN's own ordering.
type StandingsRow struct {
	Rank   int
	Team   Team
	Values []string // stat values, parallel to the group's Columns
}

// RowCount is the total number of team rows across all groups โ€” the size of the
// flattened selection space the standings cursor walks.
func (s Standings) RowCount() int {
	n := 0
	for _, g := range s.Groups {
		n += len(g.Rows)
	}
	return n
}

// RowAt returns the team row at flattened index i (across groups, in order),
// ok=false if i is out of range.
func (s Standings) RowAt(i int) (StandingsRow, bool) {
	for _, g := range s.Groups {
		if i < len(g.Rows) {
			return g.Rows[i], true
		}
		i -= len(g.Rows)
	}
	return StandingsRow{}, false
}

// TeamSchedule is a team's full season schedule (past results + upcoming
// fixtures) from ESPN's team-schedule endpoint, beyond the polled fetch window.
type TeamSchedule struct {
	Team   Team
	Season string // e.g. "2026 Regular Season"
	Games  []Game // chronological; finals carry scores, pre-games are upcoming
}