urn

package module
v0.0.0-...-711e86b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 4, 2023 License: MIT Imports: 5 Imported by: 13

README

urn - Package offering URN creation and validation

Copyright (c) 2022, Geert JM Vanderkelen

The Go urn package creates and validates Uniform Resource Names (URNs) based on RFC8141.

Overview

Package urn helps to create valid URNs and offers functionality to parse or validate strings as URN based on RFC8141.

Quote from the RFC:

A Uniform Resource Name (URN) is a Uniform Resource Identifier (URI) that is assigned under the "urn" URI scheme and a particular URN namespace, with the intent that the URN will be a persistent, location-independent resource identifier.

This is a simple implementation and could probably use some performance tricks. We focus first to be compliant with the RFC.

Example URNs:

  • urn:isbn:978-0135800911, with namespace isbn and specific string a book's ISBN13 978-0135800911
  • urn:ietf:rfc:8141, the IETF (Internet Engineering Task Force) using URN namespace 'ietf' to reference the RFC (Request For Comment) on which this package is based on.

Quick Start

Examples can be found in the examples_test.go file.

Generating a URN

One can simply generate a URN using string concatenation. However, using the urn.New() function, the NID and NSS are validated.

package main

import (
  "fmt"
  "log"

  "github.com/golistic/urn"
)

func main() {
  u, err := urn.New("ietf", "rfc:8141")
  if err != nil {
    log.Fatalln(err)
  }
  fmt.Printf("%s", u)
}
Validating a URN

Using the urn.Validates you can simply check whether a URN is valid. The same can be achieved using urn.Parse and checking for errors.

package main

import (
  "fmt"

  "github.com/golistic/urn"
)

func main() {
  if urn.Validates("urn:ietf:rfc:8141#section-3") {
    fmt.Println("valid!")
  }

  if !urn.Validates("urn:ie+tf:rfc:8141#section-3") {
    fmt.Println("not valid!")
  }
}

License

Distributed under the MIT license. See LICENSE.txt for more information.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsComponent

func IsComponent(s string) bool

IsComponent verifies whether s is a valid URN fragment.

func Validates

func Validates(s string) bool

Validates verifies whether s can be parsed as URN.

Example
package main

import (
	"fmt"

	"github.com/golistic/urn"
)

func main() {
	if urn.Validates("urn:ietf:rfc:8141#section-3") {
		fmt.Println("valid!")
	}

	if !urn.Validates("urn:ie+tf:rfc:8141#section-3") {
		fmt.Println("not valid!")
	}

}
Output:

valid!
not valid!

Types

type Option

type Option func(*urnOptions)

Option is the functional option type used with New().

func WithFragment

func WithFragment(c string) Option

WithFragment is a functional option setting the f-component of the URN; the part introduced by the number sign `#` (same syntax as the URI fragment component).

func WithNotLowerCaseNSS

func WithNotLowerCaseNSS() Option

WithNotLowerCaseNSS will not lower-case the NSS, but leave it as specified to New() or Parse(). Note that when check whether URNs are equivalent, the NSS is considered case-insensitive.

func WithQuery

func WithQuery(c string) Option

WithQuery is a functional option setting the q-component of the URN; the part introduced by `?=` (not `?` alone as is the case for a URI).

func WithResolution

func WithResolution(c string) Option

WithResolution is a functional option setting the r-component of the URN; the part after introduced by `?+`.

type URN

type URN struct {
	NID string
	NSS string

	// Original is only set when parsing a URN from a string using Parse.
	Original string
	// contains filtered or unexported fields
}

URN is the representation of a URN as defined by RFC 8141.

The syntax of a URN is: `urn:<NID>:<NSS>#fragment`. NID stands for Namespace Identifier, and NSS for Namespace Specific String.

See RFC 8141 https://tools.ietf.org/html/rfc8141

func New

func New(nid, nss string, options ...Option) (*URN, error)

New returns a new instance of URN with nid as Namespace Identifier and nss as Namespace Specific String. The r-, q-, and f-components can be set through their respective functional options WithResolution, WithQuery, and WithFragment. The NSS is lower cased according the RFC. If this is not wanted, use the option WithNotLowerCaseNSS.

Example
package main

import (
	"fmt"
	"log"

	"github.com/golistic/urn"
)

func main() {
	u, err := urn.New("ietf", "rfc:8141")
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Printf("%s", u)

}
Output:

urn:ietf:rfc:8141

func Parse

func Parse(s string, options ...Option) (*URN, error)

Parse tries to parse s into a URN object.

Example
package main

import (
	"fmt"
	"log"

	"github.com/golistic/urn"
)

func main() {
	u, err := urn.Parse("urn:ietf:rfc:8141#section-3")
	if err != nil {
		log.Fatalln(err)
	}

	fmt.Printf("%s : %v\n", u, u.Equal(&urn.URN{NID: "ietf", NSS: "rfc:8141"}))

}
Output:

urn:ietf:rfc:8141#section-3 : true

func (*URN) Equal

func (u *URN) Equal(o *URN) bool

Equal reports whether o and u represent the same URN.

Example
package main

import (
	"fmt"

	"github.com/golistic/urn"
)

func main() {
	// err handling left out for sake of brevity
	u, _ := urn.New("ietf", "rfc:8141")
	equalNID, _ := urn.New("IETF", "rfc:8141", urn.WithNotLowerCaseNSS())
	fmt.Printf("%s == %s : %v\n", u, equalNID, u.Equal(equalNID))

	notEqualNSS, _ := urn.New("ietf", "RFC:8141")
	fmt.Printf("%s == %s : %v\n", u, notEqualNSS, u.Equal(notEqualNSS))

	// components are ignored when determining equivalence
	withComponent, _ := urn.New("ietf", "rfc:8141", urn.WithFragment("section-3"))
	fmt.Printf("%s == %s : %v\n", u, withComponent, u.Equal(withComponent))

}
Output:

urn:ietf:rfc:8141 == urn:IETF:rfc:8141 : true
urn:ietf:rfc:8141 == urn:ietf:RFC:8141 : false
urn:ietf:rfc:8141 == urn:ietf:rfc:8141#section-3 : true

func (*URN) FComponent

func (u *URN) FComponent() string

func (*URN) IsZero

func (u *URN) IsZero() bool

IsZero reports whether u has NSS and NID set.

func (*URN) MarshalJSON

func (u *URN) MarshalJSON() ([]byte, error)

MarshalJSON returns the JSON encoding of u.

func (*URN) QComponent

func (u *URN) QComponent() string

func (*URN) RComponent

func (u *URN) RComponent() string

func (*URN) SetFComponent

func (u *URN) SetFComponent(c string) error

func (*URN) SetQComponent

func (u *URN) SetQComponent(c string) error

func (*URN) SetRComponent

func (u *URN) SetRComponent(c string) error

func (*URN) String

func (u *URN) String() string

String returns the string representation of u.

func (*URN) UnmarshalJSON

func (u *URN) UnmarshalJSON(data []byte) error

UnmarshalJSON parses the JSON-encoded data and stores the result in u.

Note that the NID and NSS are being lower-cased; optional components not. The Original field of u will contain the original.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL