scope/internal/cards/cards.go

89 lines
2.0 KiB
Go
Raw Normal View History

2021-12-08 17:24:05 +00:00
package cards
import (
"errors"
"html/template"
"sort"
)
var ErrCardRegistered = errors.New("card with that name has already been registered")
// cardRegistration represents a card that has been registered
type cardRegistration struct {
name string
priority int
newFn NewCardFunc
}
// cards stores all registered cards
var cards = []cardRegistration{}
// NewCardFunc creates and returns a new card.
// This should not be an expensive operation
type NewCardFunc func(query, userAgent string) Card
// Card represents a search result card
type Card interface {
// RunQuery runs any HTTP or other requests
RunQuery() error
// Returned returns whether the query
// returned any information
Returned() bool
// Matches returns whether the query matches
// for the card
Matches() bool
// StripKey removes the key words and returns
// the updated query
StripKey() string
// Title returns the card title
Title() string
// Content returns the contents of the card
Content() template.HTML
// Footer returns the contents of the card footer
Footer() template.HTML
// Head returns any extras to include in <head>
Head() template.HTML
}
// Register adds a new card to the library
func Register(name string, priority int, fn NewCardFunc) {
// For every registered card
for _, cardReg := range cards {
// If priority already exists, increase
if cardReg.priority == priority {
priority++
}
// If card already registered, return
if cardReg.name == name {
return
}
}
// Add card to slice
cards = append(cards, cardRegistration{name, priority, fn})
}
// GetCard returns a matching registered card
func GetCard(query, userAgent string) Card {
// Sort slice by priority
sort.Slice(cards, func(i, j int) bool {
return cards[i].priority < cards[j].priority
})
// For every registered card
for _, cardReg := range cards {
// Create new card
card := cardReg.newFn(query, userAgent)
// If card matches, return it
if card.Matches() {
return card
}
}
return nil
}