package cards import ( "html/template" "sort" ) // 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() 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 }