Files
weatherreporter/internal/cli/report_date.go

76 lines
2.1 KiB
Go

package cli
import (
"errors"
"fmt"
"time"
"gitea.maximumdirect.net/eric/weatherreporter/internal/app"
"gitea.maximumdirect.net/eric/weatherreporter/internal/timeutil"
)
var (
errReportDateRequired = errors.New("report date is required")
errReportDateNotAccepted = errors.New("report does not accept a date")
)
type reportDatePolicy struct {
acceptsDate bool
requiresDate bool
defaultsToLocalDate bool
}
func reportDatePolicyFor(report app.ReportKind) reportDatePolicy {
switch report {
case app.ReportDaily:
return reportDatePolicy{acceptsDate: true, requiresDate: true}
case app.ReportToday:
return reportDatePolicy{acceptsDate: true, defaultsToLocalDate: true}
default:
return reportDatePolicy{}
}
}
func addReportDateFlag(fs interface {
StringVar(*string, string, string, string)
}, report app.ReportKind, value *string) {
if reportDatePolicyFor(report).acceptsDate {
fs.StringVar(value, "date", "", "report date in YYYY-MM-DD")
}
}
func reportDateRequiredError(action string, report app.ReportKind, value string) error {
if reportDatePolicyFor(report).requiresDate && value == "" {
return fmt.Errorf("%s %s requires --date YYYY-MM-DD", action, report)
}
return nil
}
func resolveActionReportDate(action string, report app.ReportKind, value string, location *time.Location, now time.Time) (time.Time, error) {
date, err := resolveReportDate(report, value, location, now)
if errors.Is(err, errReportDateRequired) {
return time.Time{}, fmt.Errorf("%s %s requires --date YYYY-MM-DD", action, report)
}
return date, err
}
func resolveReportDate(report app.ReportKind, value string, location *time.Location, now time.Time) (time.Time, error) {
policy := reportDatePolicyFor(report)
if !policy.acceptsDate {
if value != "" {
return time.Time{}, errReportDateNotAccepted
}
return time.Time{}, nil
}
if value == "" {
if policy.requiresDate {
return time.Time{}, errReportDateRequired
}
if policy.defaultsToLocalDate {
return timeutil.LocalDate(now, location), nil
}
return time.Time{}, nil
}
return timeutil.ParseLocalDate(value, location)
}