110 lines
2.1 KiB
Go
110 lines
2.1 KiB
Go
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
|
|
|
package identity
|
|
|
|
import (
|
|
"os"
|
|
"fmt"
|
|
"strings"
|
|
"net/url"
|
|
"feudal/sequence"
|
|
)
|
|
|
|
var Serial sequence.Serial32
|
|
|
|
var spid uint64
|
|
var serial uint64
|
|
var hostname string
|
|
|
|
type Addresser interface {
|
|
Address() string
|
|
}
|
|
|
|
type Identifier interface {
|
|
Addresser
|
|
Instance() string
|
|
Path() string
|
|
Hostname() string
|
|
String() string
|
|
Parent() Identifier
|
|
CreateChild(string) Identifier
|
|
}
|
|
|
|
type Id struct {
|
|
parent Identifier
|
|
Name string
|
|
url *url.URL
|
|
instance string
|
|
}
|
|
|
|
func init() {
|
|
Serial = sequence.NewSerial32()
|
|
spid = uint64(os.Getpid()) << 32
|
|
hostname, _ = os.Hostname()
|
|
}
|
|
|
|
func New(parent Identifier, name string) Identifier {
|
|
url,_ := url.Parse(parent.Address())
|
|
url.Path += "/" + name
|
|
i := &Id{ parent: parent, Name: name, url: url, instance: InstanceId() }
|
|
return i
|
|
}
|
|
|
|
func NewRoot(name string) Identifier {
|
|
return &Id{ parent: nil, Name: name, url: &url.URL{ Scheme: "feudal", User: url.User(name), Host: hostname, Path: "" }, instance: InstanceId() }
|
|
}
|
|
|
|
func NewFromAddress(address string) Identifier {
|
|
id := &Id{ parent: nil, instance: InstanceId() }
|
|
id.url,_ = url.Parse(address)
|
|
|
|
elements := strings.Split(id.url.Path, "/")
|
|
le := len(elements)
|
|
|
|
if le == 0 {
|
|
id.Name = id.url.User.Username()
|
|
} else {
|
|
id.Name = elements[le - 1]
|
|
}
|
|
return id
|
|
}
|
|
|
|
func InstanceId() string {
|
|
return fmt.Sprintf("%x", spid | uint64(Serial()))
|
|
}
|
|
|
|
func (i *Id) Instance() string {
|
|
return i.instance
|
|
}
|
|
|
|
func (i *Id) Path() string {
|
|
return i.url.Path
|
|
}
|
|
|
|
func (i *Id) Hostname() string {
|
|
return i.url.Hostname()
|
|
}
|
|
|
|
func (parent *Id) CreateChild(name string) Identifier {
|
|
url,_ := url.Parse(parent.Address())
|
|
url.Path += "/" + name
|
|
i := &Id{ parent: parent, Name: name, url: url, instance: InstanceId() }
|
|
return i
|
|
}
|
|
|
|
func (i *Id) Parent() Identifier {
|
|
return i.parent
|
|
}
|
|
|
|
func (i *Id) Elements() []string {
|
|
return strings.Split(i.url.Path, "/")
|
|
}
|
|
|
|
func (i *Id) String() string {
|
|
return i.Address() + "#" + i.instance
|
|
}
|
|
|
|
func (i *Id) Address() string {
|
|
return i.url.String()
|
|
}
|