urn.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package urn
  2. import (
  3. "strings"
  4. )
  5. // URN represents an Uniform Resource Name.
  6. //
  7. // The general form represented is:
  8. //
  9. // urn:<id>:<ss>
  10. //
  11. // Details at https://tools.ietf.org/html/rfc2141.
  12. type URN struct {
  13. prefix string // Static prefix. Equal to "urn" when empty.
  14. ID string // Namespace identifier
  15. SS string // Namespace specific string
  16. norm string // Normalized namespace specific string
  17. }
  18. // Normalize turns the receiving URN into its norm version.
  19. //
  20. // Which means: lowercase prefix, lowercase namespace identifier, and immutate namespace specific string chars (except <hex> tokens which are lowercased).
  21. func (u *URN) Normalize() *URN {
  22. return &URN{
  23. prefix: "urn",
  24. ID: strings.ToLower(u.ID),
  25. SS: u.norm,
  26. }
  27. }
  28. // Equal checks the lexical equivalence of the current URN with another one.
  29. func (u *URN) Equal(x *URN) bool {
  30. return *u.Normalize() == *x.Normalize()
  31. }
  32. // String reassembles the URN into a valid URN string.
  33. //
  34. // This requires both ID and SS fields to be non-empty.
  35. // Otherwise it returns an empty string.
  36. //
  37. // Default URN prefix is "urn".
  38. func (u *URN) String() string {
  39. var res string
  40. if u.ID != "" && u.SS != "" {
  41. if u.prefix == "" {
  42. res += "urn"
  43. }
  44. res += u.prefix + ":" + u.ID + ":" + u.SS
  45. }
  46. return res
  47. }
  48. // Parse is responsible to create an URN instance from a byte array matching the correct URN syntax.
  49. func Parse(u []byte) (*URN, bool) {
  50. urn, err := NewMachine().Parse(u)
  51. if err != nil {
  52. return nil, false
  53. }
  54. return urn, true
  55. }