parse.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package uuid
  2. import (
  3. "encoding/hex"
  4. "github.com/golang-plus/errors"
  5. )
  6. // Parse parses the UUID string.
  7. func Parse(str string) (UUID, error) {
  8. length := len(str)
  9. buffer := make([]byte, 16)
  10. indexes := []int{}
  11. switch length {
  12. case 36:
  13. if str[8] != '-' || str[13] != '-' || str[18] != '-' || str[23] != '-' {
  14. return Nil, errors.Newf("format of UUID string %q is invalid, it should be xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)", str)
  15. }
  16. indexes = []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34}
  17. case 32:
  18. indexes = []int{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}
  19. default:
  20. return Nil, errors.Newf("length of UUID string %q is invalid, it should be 36 (standard) or 32 (without dash)", str)
  21. }
  22. var err error
  23. for i, v := range indexes {
  24. if c, e := hex.DecodeString(str[v : v+2]); e == nil {
  25. buffer[i] = c[0]
  26. } else {
  27. err = e
  28. break
  29. }
  30. }
  31. if err != nil {
  32. return Nil, errors.Wrapf(err, "UUID string %q is invalid", str)
  33. }
  34. uuid := UUID{}
  35. copy(uuid[:], buffer)
  36. if !uuid.Equal(Nil) {
  37. if uuid.Layout() == LayoutInvalid {
  38. return Nil, errors.Newf("layout of UUID %q is invalid", str)
  39. }
  40. if uuid.Version() == VersionUnknown {
  41. return Nil, errors.Newf("version of UUID %q is unknown", str)
  42. }
  43. }
  44. return uuid, nil
  45. }
  46. // IsValid reports whether the passed string is a valid uuid string.
  47. func IsValid(uuid string) bool {
  48. _, err := Parse(uuid)
  49. return err == nil
  50. }