status.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package status
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "strconv"
  7. "strings"
  8. "time"
  9. )
  10. type syncStatus uint8
  11. const (
  12. None syncStatus = iota
  13. Failed
  14. Success
  15. Syncing
  16. PreSyncing
  17. Paused
  18. Disabled
  19. )
  20. type MirrorStatus struct {
  21. Name string
  22. Status syncStatus
  23. LastUpdate time.Time
  24. Upstream string
  25. Size string // approximate size
  26. }
  27. func (s MirrorStatus) MarshalJSON() ([]byte, error) {
  28. m := map[string]interface{}{
  29. "name": s.Name,
  30. "status": s.Status,
  31. "last_update": s.LastUpdate.Format("2006-01-02 15:04:05"),
  32. "last_update_ts": fmt.Sprintf("%d", s.LastUpdate.Unix()),
  33. "size": s.Size,
  34. "upstream": s.Upstream,
  35. }
  36. return json.Marshal(m)
  37. }
  38. func (s *MirrorStatus) UnmarshalJSON(v []byte) error {
  39. var m map[string]interface{}
  40. err := json.Unmarshal(v, &m)
  41. if err != nil {
  42. return err
  43. }
  44. if name, ok := m["name"]; ok {
  45. if s.Name, ok = name.(string); !ok {
  46. return errors.New("name should be a string")
  47. }
  48. } else {
  49. return errors.New("key `name` does not exist in the json")
  50. }
  51. if upstream, ok := m["upstream"]; ok {
  52. if s.Upstream, ok = upstream.(string); !ok {
  53. return errors.New("upstream should be a string")
  54. }
  55. } else {
  56. return errors.New("key `upstream` does not exist in the json")
  57. }
  58. if size, ok := m["size"]; ok {
  59. if s.Size, ok = size.(string); !ok {
  60. return errors.New("size should be a string")
  61. }
  62. } else {
  63. return errors.New("key `size` does not exist in the json")
  64. }
  65. // tricky: status
  66. if status, ok := m["status"]; ok {
  67. if ss, ok := status.(string); ok {
  68. err := json.Unmarshal([]byte(`"`+ss+`"`), &(s.Status))
  69. if err != nil {
  70. return err
  71. }
  72. } else {
  73. return errors.New("status should be a string")
  74. }
  75. } else {
  76. return errors.New("key `status` does not exist in the json")
  77. }
  78. // tricky: last update
  79. if lastUpdate, ok := m["last_update_ts"]; ok {
  80. if sts, ok := lastUpdate.(string); ok {
  81. ts, err := strconv.Atoi(sts)
  82. if err != nil {
  83. return fmt.Errorf("last_update_ts should be a interger, got: %s", sts)
  84. }
  85. s.LastUpdate = time.Unix(int64(ts), 0)
  86. } else {
  87. return fmt.Errorf("last_update_ts should be a string of integer, got: %s", lastUpdate)
  88. }
  89. } else {
  90. return errors.New("key `last_update_ts` does not exist in the json")
  91. }
  92. return nil
  93. }
  94. func (s syncStatus) MarshalJSON() ([]byte, error) {
  95. var strStatus string
  96. switch s {
  97. case None:
  98. strStatus = "none"
  99. case Success:
  100. strStatus = "success"
  101. case Syncing:
  102. strStatus = "syncing"
  103. case PreSyncing:
  104. strStatus = "pre-syncing"
  105. case Paused:
  106. strStatus = "paused"
  107. case Disabled:
  108. strStatus = "disabled"
  109. default:
  110. return []byte{}, errors.New("Invalid status value")
  111. }
  112. return json.Marshal(strStatus)
  113. }
  114. func (s *syncStatus) UnmarshalJSON(v []byte) error {
  115. sv := strings.Trim(string(v), `"`)
  116. switch sv {
  117. case "none":
  118. *s = None
  119. case "success":
  120. *s = Success
  121. case "syncing":
  122. *s = Syncing
  123. case "pre-syncing":
  124. *s = PreSyncing
  125. case "paused":
  126. *s = Paused
  127. case "disabled":
  128. *s = Disabled
  129. default:
  130. return fmt.Errorf("Invalid status value: %s", string(v))
  131. }
  132. return nil
  133. }