about summary refs log tree commit diff stats
path: root/registry/types.go
diff options
context:
space:
mode:
Diffstat (limited to 'registry/types.go')
-rw-r--r--registry/types.go148
1 files changed, 148 insertions, 0 deletions
diff --git a/registry/types.go b/registry/types.go
new file mode 100644
index 0000000..eb8eee1
--- /dev/null
+++ b/registry/types.go
@@ -0,0 +1,148 @@
+/*
+Copyright (c) 2019 Ben Morrison (gbmor)
+
+This file is part of Registry.
+
+Registry is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Registry is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Registry.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+// Package registry implements functions and types that assist
+// in the creation and management of a twtxt registry.
+package registry // import "git.sr.ht/~gbmor/getwtxt/registry"
+
+import (
+	"net"
+	"net/http"
+	"sync"
+	"time"
+)
+
+// Registrar implements the minimum amount of methods
+// for a functioning Registry.
+type Registrar interface {
+	Put(user *User) error
+	Get(urlKey string) (*User, error)
+	DelUser(urlKey string) error
+	UpdateUser(urlKey string) error
+	GetUserStatuses(urlKey string) (TimeMap, error)
+	GetStatuses() (TimeMap, error)
+}
+
+// User holds a given user's information
+// and statuses.
+type User struct {
+	// Provided to aid in concurrency-safe
+	// reads and writes. In most cases, the
+	// mutex in the associated Index should be
+	// used instead. This mutex is provided
+	// should the library user need to access
+	// a User independently of an Index.
+	Mu sync.RWMutex
+
+	// Nick is the user-specified nickname.
+	Nick string
+
+	// The URL of the user's twtxt file
+	URL string
+
+	// The reported last modification date
+	// of the user's twtxt.txt file.
+	LastModified string
+
+	// The IP address of the user is optionally
+	// recorded when submitted via POST.
+	IP net.IP
+
+	// The timestamp, in RFC3339 format,
+	// reflecting when the user was added.
+	Date string
+
+	// A TimeMap of the user's statuses
+	// from their twtxt file.
+	Status TimeMap
+}
+
+// Registry enables the bulk of a registry's
+// user data storage and access.
+type Registry struct {
+	// Provided to aid in concurrency-safe
+	// reads and writes to a given registry
+	// Users map.
+	Mu sync.RWMutex
+
+	// The registry's user data is contained
+	// in this map. The functions within this
+	// library expect the key to be the URL of
+	// a given user's twtxt file.
+	Users map[string]*User
+
+	// The client to use for HTTP requests.
+	// If nil is passed to NewIndex(), a
+	// client with a 10 second timeout
+	// and all other values as default is
+	// used.
+	HTTPClient *http.Client
+}
+
+// TimeMap holds extracted and processed user data as a
+// string. A time.Time value is used as the key.
+type TimeMap map[time.Time]string
+
+// TimeSlice is a slice of time.Time used for sorting
+// a TimeMap by timestamp.
+type TimeSlice []time.Time
+
+// NewUser returns a pointer to an initialized User
+func NewUser() *User {
+	return &User{
+		Mu:     sync.RWMutex{},
+		Status: NewTimeMap(),
+	}
+}
+
+// New returns an initialized Registry instance.
+func New(client *http.Client) *Registry {
+	return &Registry{
+		Mu:         sync.RWMutex{},
+		Users:      make(map[string]*User),
+		HTTPClient: client,
+	}
+}
+
+// NewTimeMap returns an initialized TimeMap.
+func NewTimeMap() TimeMap {
+	return make(TimeMap)
+}
+
+// Len returns the length of the TimeSlice to be sorted.
+// This helps satisfy sort.Interface.
+func (t TimeSlice) Len() int {
+	return len(t)
+}
+
+// Less returns true if the timestamp at index i is after
+// the timestamp at index j in a given TimeSlice. This results
+// in a descending (reversed) sort order for timestamps rather
+// than ascending.
+// This helps satisfy sort.Interface.
+func (t TimeSlice) Less(i, j int) bool {
+	return t[i].After(t[j])
+}
+
+// Swap transposes the timestamps at the two given indices
+// for the TimeSlice receiver.
+// This helps satisfy sort.Interface.
+func (t TimeSlice) Swap(i, j int) {
+	t[i], t[j] = t[j], t[i]
+}