Files
wehub-resource-sync ead81af521
Deploy to GitHub Pages / deploy (push) Failing after 0s
CI / go (push) Has been cancelled
CI / build (darwin, macos-14) (push) Has been cancelled
CI / build (windows, windows-2025) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:13 +08:00

153 lines
3.0 KiB
Go

package model
import (
"fmt"
"strconv"
"strings"
"time"
)
func parseJumpTarget(raw string) (time.Duration, error) {
s := strings.TrimSpace(raw)
if s == "" {
return 0, fmt.Errorf("use ss, mm:ss, or hh:mm:ss format")
}
parts := strings.Split(s, ":")
switch len(parts) {
case 1:
secs, err := parseTotalSeconds(parts[0])
if err != nil {
return 0, err
}
return time.Duration(secs) * time.Second, nil
case 2:
minPart := normalizeClockField(parts[0])
secPart := normalizeClockField(parts[1])
mins, err := parseTotalMinutes(minPart)
if err != nil {
return 0, err
}
secs, err := parseClockSeconds(secPart)
if err != nil {
return 0, err
}
return time.Duration(mins)*time.Minute + time.Duration(secs)*time.Second, nil
case 3:
hourPart := normalizeClockField(parts[0])
minPart := normalizeClockField(parts[1])
secPart := normalizeClockField(parts[2])
hours, err := parseTotalHours(hourPart)
if err != nil {
return 0, err
}
mins, err := parseClockMinutes(minPart)
if err != nil {
return 0, err
}
secs, err := parseClockSeconds(secPart)
if err != nil {
return 0, err
}
return time.Duration(hours)*time.Hour +
time.Duration(mins)*time.Minute +
time.Duration(secs)*time.Second, nil
default:
return 0, fmt.Errorf("use ss, mm:ss, or hh:mm:ss format")
}
}
func normalizeClockField(s string) string {
s = strings.TrimSpace(s)
if s == "" {
return "0"
}
return s
}
func parseTotalSeconds(s string) (int, error) {
secs, err := parseNonNegativeInt(strings.TrimSpace(s), "seconds")
if err != nil {
return 0, err
}
return secs, nil
}
func parseTotalMinutes(s string) (int, error) {
mins, err := parseNonNegativeInt(s, "minutes")
if err != nil {
return 0, err
}
return mins, nil
}
func parseTotalHours(s string) (int, error) {
hours, err := parseNonNegativeInt(s, "hours")
if err != nil {
return 0, err
}
return hours, nil
}
func parseClockMinutes(s string) (int, error) {
if len(s) > 2 {
return 0, fmt.Errorf("minutes must be 0-59")
}
mins, err := parseNonNegativeInt(s, "minutes")
if err != nil {
return 0, err
}
if mins > 59 {
return 0, fmt.Errorf("minutes must be 0-59")
}
return mins, nil
}
func parseClockSeconds(s string) (int, error) {
if len(s) > 2 {
return 0, fmt.Errorf("seconds must be 0-59")
}
secs, err := parseNonNegativeInt(s, "seconds")
if err != nil {
return 0, err
}
if secs > 59 {
return 0, fmt.Errorf("seconds must be 0-59")
}
return secs, nil
}
func parseNonNegativeInt(s, label string) (int, error) {
if s == "" {
return 0, fmt.Errorf("%s must be a number", label)
}
for _, r := range s {
if r < '0' || r > '9' {
return 0, fmt.Errorf("%s must be a number", label)
}
}
v, err := strconv.Atoi(s)
if err != nil {
return 0, fmt.Errorf("%s must be a number", label)
}
return v, nil
}
func formatJumpClock(d time.Duration) string {
if d < 0 {
d = 0
}
total := int(d.Seconds())
mm := total / 60
ss := total % 60
return fmt.Sprintf("%02d:%02d", mm, ss)
}
func formatJumpPlaceholder(d time.Duration) string {
return "00:00"
}