Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/entry/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "time"
const (
TypeLog = "log"
TypeCheckout = "checkout"
TypeSubmit = "submit"
)

// Entry represents a single time log entry (a "time commit").
Expand Down
51 changes: 12 additions & 39 deletions internal/entry/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,19 @@ func ReadEntry(homeDir, slug, id string) (Entry, error) {
return e, nil
}

// ReadAllEntries reads all log entry files from a project's log directory.
func ReadAllEntries(homeDir, slug string) ([]Entry, error) {
// readAllOfType reads all entries of a given type from a project's log directory.
func readAllOfType[T any](homeDir, slug, entryType string) ([]T, error) {
files, err := readAllFiles(homeDir, slug)
if err != nil {
return nil, err
}

var entries []Entry
var entries []T
for _, f := range files {
if !matchesType(f.data, TypeLog) {
if !matchesType(f.data, entryType) {
continue
}
var e Entry
var e T
if err := json.Unmarshal(f.data, &e); err != nil {
continue
}
Expand All @@ -147,6 +147,11 @@ func ReadAllEntries(homeDir, slug string) ([]Entry, error) {
return entries, nil
}

// ReadAllEntries reads all log entry files from a project's log directory.
func ReadAllEntries(homeDir, slug string) ([]Entry, error) {
return readAllOfType[Entry](homeDir, slug, TypeLog)
}

// IsCheckoutEntry checks if the file at the given path exists and is a checkout entry.
func IsCheckoutEntry(homeDir, slug, id string) bool {
path, err := EntryPath(homeDir, slug, id)
Expand Down Expand Up @@ -208,42 +213,10 @@ func WriteSubmitEntry(homeDir, slug string, e SubmitEntry) error {

// ReadAllSubmitEntries reads all submit marker entries from a project's log directory.
func ReadAllSubmitEntries(homeDir, slug string) ([]SubmitEntry, error) {
files, err := readAllFiles(homeDir, slug)
if err != nil {
return nil, err
}

var entries []SubmitEntry
for _, f := range files {
if !matchesType(f.data, TypeSubmit) {
continue
}
var e SubmitEntry
if err := json.Unmarshal(f.data, &e); err != nil {
continue
}
entries = append(entries, e)
}
return entries, nil
return readAllOfType[SubmitEntry](homeDir, slug, TypeSubmit)
}

// ReadAllCheckoutEntries reads all checkout entries from a project's log directory.
func ReadAllCheckoutEntries(homeDir, slug string) ([]CheckoutEntry, error) {
files, err := readAllFiles(homeDir, slug)
if err != nil {
return nil, err
}

var entries []CheckoutEntry
for _, f := range files {
if !matchesType(f.data, TypeCheckout) {
continue
}
var e CheckoutEntry
if err := json.Unmarshal(f.data, &e); err != nil {
continue
}
entries = append(entries, e)
}
return entries, nil
return readAllOfType[CheckoutEntry](homeDir, slug, TypeCheckout)
}
2 changes: 0 additions & 2 deletions internal/entry/submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package entry

import "time"

const TypeSubmit = "submit"

// SubmitEntry marks a date range as submitted.
type SubmitEntry struct {
ID string `json:"id"`
Expand Down
37 changes: 15 additions & 22 deletions internal/schedule/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,20 @@ func format12h(hhmm string) string {
return fmt.Sprintf("%d:%s %s", display, m, suffix)
}

func isWeekdays(days []string) bool {
if len(days) != 5 {
// matchExactSet returns true if actual contains exactly the expected strings (in any order).
func matchExactSet(actual []string, expected ...string) bool {
if len(actual) != len(expected) {
return false
}
set := map[string]bool{"MO": false, "TU": false, "WE": false, "TH": false, "FR": false}
for _, d := range days {
if _, ok := set[d]; !ok {
set := make(map[string]bool, len(expected))
for _, e := range expected {
set[e] = false
}
for _, a := range actual {
if _, ok := set[a]; !ok {
return false
}
set[d] = true
set[a] = true
}
for _, v := range set {
if !v {
Expand All @@ -200,23 +204,12 @@ func isWeekdays(days []string) bool {
return true
}

func isWeekdays(days []string) bool {
return matchExactSet(days, "MO", "TU", "WE", "TH", "FR")
}

func isWeekends(days []string) bool {
if len(days) != 2 {
return false
}
set := map[string]bool{"SA": false, "SU": false}
for _, d := range days {
if _, ok := set[d]; !ok {
return false
}
set[d] = true
}
for _, v := range set {
if !v {
return false
}
}
return true
return matchExactSet(days, "SA", "SU")
}

var dayNames = map[string]string{
Expand Down