diff options
Diffstat (limited to 'registry/types.go')
-rw-r--r-- | registry/types.go | 148 |
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] +} |