timedurationvalue.go
1 package flag 2 3 import ( 4 "fmt" 5 "regexp" 6 "strconv" 7 "strings" 8 "time" 9 ) 10 11 const timeDurationRegexPattern string = `[0-9]{1,4}\s+(days?|hours?|minutes?|seconds?)` 12 13 type TimeDurationValue struct { 14 Duration time.Duration 15 } 16 17 func NewTimeDurationValue() TimeDurationValue { 18 return TimeDurationValue{ 19 Duration: time.Duration(0), 20 } 21 } 22 23 func (v TimeDurationValue) String() string { 24 return v.Duration.String() 25 } 26 27 func (v *TimeDurationValue) Set(value string) error { 28 pattern := regexp.MustCompile(timeDurationRegexPattern) 29 matches := pattern.FindAllString(value, -1) 30 31 days, hours, minutes, seconds := 0, 0, 0, 0 32 33 var err error 34 35 for ind := range len(matches) { 36 switch { 37 case strings.Contains(matches[ind], "day"): 38 days, err = parseInt(matches[ind]) 39 if err != nil { 40 return fmt.Errorf("unable to parse the number of days from %s: %w", matches[ind], err) 41 } 42 case strings.Contains(matches[ind], "hour"): 43 hours, err = parseInt(matches[ind]) 44 if err != nil { 45 return fmt.Errorf("unable to parse the number of hours from %s: %w", matches[ind], err) 46 } 47 case strings.Contains(matches[ind], "minute"): 48 minutes, err = parseInt(matches[ind]) 49 if err != nil { 50 return fmt.Errorf("unable to parse the number of minutes from %s: %w", matches[ind], err) 51 } 52 case strings.Contains(matches[ind], "second"): 53 seconds, err = parseInt(matches[ind]) 54 if err != nil { 55 return fmt.Errorf("unable to parse the number of seconds from %s: %w", matches[ind], err) 56 } 57 } 58 } 59 60 durationValue := (days * 86400) + (hours * 3600) + (minutes * 60) + seconds 61 62 v.Duration = time.Duration(durationValue) * time.Second 63 64 return nil 65 } 66 67 func parseInt(text string) (int, error) { 68 split := strings.SplitN(text, " ", 2) 69 if len(split) != 2 { 70 return 0, fmt.Errorf("unexpected number of split for %s: want 2, got %d", text, len(split)) 71 } 72 73 output, err := strconv.Atoi(split[0]) 74 if err != nil { 75 return 0, fmt.Errorf("unable to convert %s to an integer: %w", text, err) 76 } 77 78 return output, nil 79 }