parse.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package version
  2. import (
  3. "strconv"
  4. "strings"
  5. )
  6. const (
  7. sectionMajor = 0
  8. sectionMinor = 1
  9. sectionPatch = 2
  10. sectionExtension = 3
  11. )
  12. func MustParse(str string) *Version {
  13. v, err := Parse(str)
  14. if err != nil {
  15. panic(err)
  16. }
  17. return v
  18. }
  19. func Parse(str string) (*Version, error) {
  20. v := &Version{Text: string(str)}
  21. if len(str) == 0 {
  22. return nil, ErrInvalidVersion
  23. }
  24. section := sectionMajor
  25. chars := []byte{}
  26. commit := func() error {
  27. if len(chars) == 0 {
  28. return ErrInvalidVersion
  29. }
  30. if section < sectionExtension {
  31. n, err := strconv.Atoi(string(chars))
  32. if err != nil {
  33. return ErrInvalidVersion
  34. }
  35. switch section {
  36. case sectionMajor:
  37. v.Major = n
  38. case sectionMinor:
  39. v.Minor = n
  40. case sectionPatch:
  41. v.Patch = n
  42. }
  43. } else {
  44. v.Extension = string(chars)
  45. }
  46. chars = []byte{}
  47. return nil
  48. }
  49. for i := 0; i < len(str); i++ {
  50. c := str[i]
  51. if i == 0 && strings.IndexByte("vV", c) > -1 {
  52. continue
  53. }
  54. if section < sectionExtension {
  55. if strings.IndexByte("0123456789", c) > -1 {
  56. chars = append(chars, c)
  57. } else {
  58. if err := commit(); err != nil {
  59. return nil, err
  60. }
  61. if c == '.' {
  62. section++
  63. } else {
  64. section = sectionExtension
  65. chars = append(chars, c)
  66. }
  67. }
  68. } else {
  69. chars = append(chars, c)
  70. }
  71. }
  72. if len(chars) > 0 {
  73. if err := commit(); err != nil {
  74. return nil, err
  75. }
  76. }
  77. return v, nil
  78. }