Leonardo Di Donato пре 7 година
родитељ
комит
203993f3e7
2 измењених фајлова са 38 додато и 75 уклоњено
  1. 19 54
      urn.go
  2. 19 21
      urn_test.go

+ 19 - 54
urn.go

@@ -1,26 +1,9 @@
-// Package urn implements RFC 2141.
-//
-// It provides a parser capable, given a string respecting valid syntax as per RFC 2141, to instantiate an URN type.
-// Furthermore this package provides methods to perform normalization and lexical equivalence on URN instances.
 package urn
 
 import (
 	"strings"
-
-	pcre "github.com/gijsbers/go-pcre"
 )
 
-var re = `^
-	(?:(?P<pre>[uU][rR][nN]):(?!urn:))
-
-	(?P<nid>[A-Za-z0-9][A-Za-z0-9-]{0,31}):
-
-	(?P<nss>(?:[A-Za-z0-9()+,\-.:=@;$_!*']|[%][A-Fa-f0-9][A-Fa-f0-9])+)
-$`
-
-var pattern = pcre.MustCompile(re, pcre.EXTENDED)
-var hexrepr = pcre.MustCompile("[%][A-F0-9]{2}", 0)
-
 // URN represents an Uniform Resource Name.
 //
 // The general form represented is:
@@ -32,23 +15,23 @@ type URN struct {
 	prefix string // Static prefix. Equal to "urn" when empty.
 	ID     string // Namespace identifier
 	SS     string // Namespace specific string
+	norm   string // Normalized namespace specific string
 }
 
-// Parse is responsible to create an URN instance from a string matching the correct URN syntax.
-func Parse(u string) (*URN, bool) {
-	matcher := pattern.MatcherString(u, 0)
-	matches := matcher.Matches()
-
-	if matches {
-		urn := &URN{}
-		urn.prefix, _ = matcher.NamedString("pre")
-		urn.ID, _ = matcher.NamedString("nid")
-		urn.SS, _ = matcher.NamedString("nss")
-
-		return urn, matches
+// Normalize turns the receiving URN into its norm version.
+//
+// Which means: lowercase prefix, lowercase namespace identifier, and immutate namespace specific string chars (except <hex> tokens which are lowercased).
+func (u *URN) Normalize() *URN {
+	return &URN{
+		prefix: "urn",
+		ID:     strings.ToLower(u.ID),
+		SS:     u.norm,
 	}
+}
 
-	return nil, matches
+// Equal checks the lexical equivalence of the current URN with another one.
+func (u *URN) Equal(x *URN) bool {
+	return *u.Normalize() == *x.Normalize()
 }
 
 // String reassembles the URN into a valid URN string.
@@ -69,30 +52,12 @@ func (u *URN) String() string {
 	return res
 }
 
-// Normalize turns the receiving URN into its norm version.
-//
-// Which means: lowercase prefix, lowercase namespace identifier, and immutate namespace specific string chars (except <hex> tokens which are lowercased).
-func (u *URN) Normalize() *URN {
-	norm := ""
-	ss := u.SS
-	matcher := hexrepr.MatcherString(ss, 0)
-	for matcher.MatchString(ss, 0) {
-		indexes := matcher.Index()
-		from := indexes[0]
-		to := indexes[1]
-		norm += ss[:from] + strings.ToLower(ss[from:to])
-		ss = ss[to:]
-	}
-	norm += ss
-
-	return &URN{
-		prefix: "urn",
-		ID:     strings.ToLower(u.ID),
-		SS:     norm,
+// Parse is responsible to create an URN instance from a byte array matching the correct URN syntax.
+func Parse(u []byte) (*URN, bool) {
+	urn, err := NewMachine().Parse(u)
+	if err != nil {
+		return nil, false
 	}
-}
 
-// Equal checks the lexical equivalence of the current URN with another one.
-func (u *URN) Equal(x *URN) bool {
-	return *u.Normalize() == *x.Normalize()
+	return urn, true
 }

+ 19 - 21
urn_test.go

@@ -3,25 +3,23 @@ package urn
 import (
 	"testing"
 
+	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
-func TestUrn(t *testing.T) {
-	for ii, tt := range tests {
-		urn, ok := Parse(tt.in)
-
-		if ok {
-			require.True(t, tt.ok, herror(ii, tt))
-			require.Equal(t, tt.obj.prefix, urn.prefix, herror(ii, tt))
-			require.Equal(t, tt.obj.ID, urn.ID, herror(ii, tt))
-			require.Equal(t, tt.obj.SS, urn.SS, herror(ii, tt))
-			require.Equal(t, tt.str, urn.String(), herror(ii, tt))
-			require.Equal(t, tt.norm, urn.Normalize().String(), herror(ii, tt))
-		} else {
-			require.False(t, tt.ok, herror(ii, tt))
-			require.Empty(t, urn, herror(ii, tt))
-		}
+func TestDefaultPrefixWhenString(t *testing.T) {
+	u := &URN{
+		ID: "pippo",
+		SS: "pluto",
 	}
+
+	assert.Equal(t, "urn:pippo:pluto", u.String())
+}
+
+func TestParseSignature(t *testing.T) {
+	urn, ok := Parse([]byte(``))
+	assert.Nil(t, urn)
+	assert.False(t, ok)
 }
 
 func TestLexicalEquivalence(t *testing.T) {
@@ -31,15 +29,15 @@ func TestLexicalEquivalence(t *testing.T) {
 
 		if oklx && okrx {
 
-			require.True(t, urnlx.Equal(urnlx))
-			require.True(t, urnrx.Equal(urnrx))
+			assert.True(t, urnlx.Equal(urnlx))
+			assert.True(t, urnrx.Equal(urnrx))
 
 			if tt.eq {
-				require.True(t, urnlx.Equal(urnrx), ierror(ii))
-				require.True(t, urnrx.Equal(urnlx), ierror(ii))
+				assert.True(t, urnlx.Equal(urnrx), ierror(ii))
+				assert.True(t, urnrx.Equal(urnlx), ierror(ii))
 			} else {
-				require.False(t, urnlx.Equal(urnrx), ierror(ii))
-				require.False(t, urnrx.Equal(urnlx), ierror(ii))
+				assert.False(t, urnlx.Equal(urnrx), ierror(ii))
+				assert.False(t, urnrx.Equal(urnlx), ierror(ii))
 			}
 		} else {
 			t.Log("Something wrong in the testing table ...")