format.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package pb
  2. import (
  3. "fmt"
  4. "strings"
  5. "time"
  6. )
  7. type Units int
  8. const (
  9. // U_NO are default units, they represent a simple value and are not formatted at all.
  10. U_NO Units = iota
  11. // U_BYTES units are formatted in a human readable way (b, Bb, Mb, ...)
  12. U_BYTES
  13. // U_DURATION units are formatted in a human readable way (3h14m15s)
  14. U_DURATION
  15. )
  16. func Format(i int64) *formatter {
  17. return &formatter{n: i}
  18. }
  19. type formatter struct {
  20. n int64
  21. unit Units
  22. width int
  23. perSec bool
  24. }
  25. func (f *formatter) Value(n int64) *formatter {
  26. f.n = n
  27. return f
  28. }
  29. func (f *formatter) To(unit Units) *formatter {
  30. f.unit = unit
  31. return f
  32. }
  33. func (f *formatter) Width(width int) *formatter {
  34. f.width = width
  35. return f
  36. }
  37. func (f *formatter) PerSec() *formatter {
  38. f.perSec = true
  39. return f
  40. }
  41. func (f *formatter) String() (out string) {
  42. switch f.unit {
  43. case U_BYTES:
  44. out = formatBytes(f.n)
  45. case U_DURATION:
  46. d := time.Duration(f.n)
  47. if d > time.Hour*24 {
  48. out = fmt.Sprintf("%dd", d/24/time.Hour)
  49. d -= (d / time.Hour / 24) * (time.Hour * 24)
  50. }
  51. out = fmt.Sprintf("%s%v", out, d)
  52. default:
  53. out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n)
  54. }
  55. if f.perSec {
  56. out += "/s"
  57. }
  58. return
  59. }
  60. // Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B
  61. func formatBytes(i int64) (result string) {
  62. switch {
  63. case i > (1024 * 1024 * 1024 * 1024):
  64. result = fmt.Sprintf("%.02f TB", float64(i)/1024/1024/1024/1024)
  65. case i > (1024 * 1024 * 1024):
  66. result = fmt.Sprintf("%.02f GB", float64(i)/1024/1024/1024)
  67. case i > (1024 * 1024):
  68. result = fmt.Sprintf("%.02f MB", float64(i)/1024/1024)
  69. case i > 1024:
  70. result = fmt.Sprintf("%.02f KB", float64(i)/1024)
  71. default:
  72. result = fmt.Sprintf("%d B", i)
  73. }
  74. result = strings.Trim(result, " ")
  75. return
  76. }