create URL codec
This commit is contained in:
9
pkg/url/log.go
Normal file
9
pkg/url/log.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package url
|
||||
|
||||
import (
|
||||
"protocol.realy.lol/pkg/lol"
|
||||
)
|
||||
|
||||
var (
|
||||
log, chk, errorf = lol.Main.Log, lol.Main.Check, lol.Main.Errorf
|
||||
)
|
||||
46
pkg/url/url.go
Normal file
46
pkg/url/url.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package url
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type U struct{ uu []byte }
|
||||
|
||||
// New creates a new URL codec.C from the provided URL, and validates it.
|
||||
func New[V ~string | []byte](ur V) (uu *U, err error) {
|
||||
uu = new(U)
|
||||
var UU *url.URL
|
||||
if UU, err = url.Parse(string(ur)); chk.E(err) {
|
||||
return
|
||||
} else {
|
||||
// if it is valid, store it
|
||||
uu.uu = []byte(UU.String())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (u *U) String() string { return string(u.uu) }
|
||||
func (u *U) Bytes() []byte { return u.uu }
|
||||
func (u *U) Equal(u2 *U) bool { return bytes.Equal(u.uu, u2.uu) }
|
||||
|
||||
func (u *U) Marshal(dst []byte) (result []byte, err error) {
|
||||
result = append(append(dst, u.uu...), '\n')
|
||||
return
|
||||
}
|
||||
|
||||
func (u *U) Unmarshal(data []byte) (rem []byte, err error) {
|
||||
rem = data
|
||||
for i, v := range rem {
|
||||
if v == '\n' {
|
||||
u.uu = rem[:i]
|
||||
rem = rem[i+1:]
|
||||
break
|
||||
}
|
||||
}
|
||||
// validate the URL and return error if not valid.
|
||||
if _, err = url.Parse(string(u.uu)); chk.E(err) {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
29
pkg/url/url_test.go
Normal file
29
pkg/url/url_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package url
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestU_Marshal_Unmarshal(t *testing.T) {
|
||||
u := "https://example.com/path/to/resource"
|
||||
var err error
|
||||
var u1 *U
|
||||
if u1, err = New(u); chk.E(err) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var m1 []byte
|
||||
if m1, err = u1.Marshal(nil); chk.E(err) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
u2 := new(U)
|
||||
var rem []byte
|
||||
if rem, err = u2.Unmarshal(m1); chk.E(err) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(rem) > 0 {
|
||||
t.Fatalf("'%s' should be empty", string(rem))
|
||||
}
|
||||
if !u2.Equal(u1) {
|
||||
t.Fatalf("u1 should be equal to u2: '%s' != '%s'", u1, u2)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user