feudal/identity/identifier.go

110 lines
2.1 KiB
Go
Raw Permalink Normal View History

2024-05-05 07:14:57 +00:00
// 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()
}