duration.go raw

   1  package duration
   2  
   3  import (
   4  	"encoding/json"
   5  	"fmt"
   6  	"log"
   7  	"strconv"
   8  	"strings"
   9  )
  10  
  11  func UnmarshalTimeRemaining(m json.RawMessage) *int {
  12  	jsonBytes, err := m.MarshalJSON()
  13  	if err != nil {
  14  		panic(jsonBytes)
  15  	}
  16  
  17  	if len(jsonBytes) == 4 && string(jsonBytes) == "null" {
  18  		return nil
  19  	}
  20  
  21  	var timeStr string
  22  	if err := json.Unmarshal(jsonBytes, &timeStr); err == nil && len(timeStr) > 0 {
  23  		dur, err := durationToSeconds(timeStr)
  24  		if err != nil {
  25  			panic(err)
  26  		}
  27  
  28  		return &dur
  29  	}
  30  
  31  	var intPtr int
  32  	if err := json.Unmarshal(jsonBytes, &intPtr); err == nil {
  33  		return &intPtr
  34  	}
  35  
  36  	log.Println("[WARN] Unexpected unmarshalTimeRemaining value: ", jsonBytes)
  37  
  38  	return nil
  39  }
  40  
  41  // durationToSeconds takes a hh:mm:ss string and returns the number of seconds.
  42  func durationToSeconds(s string) (int, error) {
  43  	multipliers := [3]int{60 * 60, 60, 1}
  44  	segs := strings.Split(s, ":")
  45  
  46  	if len(segs) > len(multipliers) {
  47  		return 0, fmt.Errorf("too many ':' separators in time duration: %s", s)
  48  	}
  49  
  50  	var d int
  51  
  52  	l := len(segs)
  53  
  54  	for i := range l {
  55  		m, err := strconv.Atoi(segs[i])
  56  		if err != nil {
  57  			return 0, err
  58  		}
  59  
  60  		d += m * multipliers[i+len(multipliers)-l]
  61  	}
  62  
  63  	return d, nil
  64  }
  65