72 lines
1.6 KiB
Go
72 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Note that in a real application using both "json" and "bson" tags in the same structure is strongly discouraged.
|
|
// We use common models for database storage and HTTP API just to make this example simple and easy to grasp.
|
|
// See our article about the idea behind this: https://threedots.tech/post/things-to-know-about-dry/
|
|
|
|
type Post struct {
|
|
ID string `json:"id" bson:"id"`
|
|
Title string `json:"title" bson:"title"`
|
|
Content string `json:"content" bson:"content"`
|
|
Author string `json:"author" bson:"author"`
|
|
Tags []string `json:"tags" bson:"tags"`
|
|
}
|
|
|
|
func NewPost(id, title, content, author string) Post {
|
|
pattern := regexp.MustCompile("#([a-zA-Z0-9]+)")
|
|
matches := pattern.FindAllStringSubmatch(content, -1)
|
|
|
|
var tags []string
|
|
tagsMap := map[string]struct{}{}
|
|
|
|
for _, tag := range matches {
|
|
tagSlug := strings.ToLower(tag[1])
|
|
|
|
_, ok := tagsMap[tagSlug]
|
|
if ok {
|
|
continue
|
|
}
|
|
|
|
tagsMap[tagSlug] = struct{}{}
|
|
tags = append(tags, tagSlug)
|
|
}
|
|
|
|
return Post{
|
|
ID: id,
|
|
Title: title,
|
|
Content: content,
|
|
Author: author,
|
|
Tags: tags,
|
|
}
|
|
}
|
|
|
|
type Feed struct {
|
|
Name string `json:"name" bson:"_id"`
|
|
Posts []Post `json:"posts" bson:"posts"`
|
|
}
|
|
|
|
type PostCreated struct {
|
|
Post Post `json:"post"`
|
|
|
|
OccurredAt time.Time `json:"occurred_at"`
|
|
}
|
|
|
|
type PostUpdated struct {
|
|
OriginalPost Post `json:"original_post"`
|
|
NewPost Post `json:"new_post"`
|
|
|
|
OccurredAt time.Time `json:"occurred_at"`
|
|
}
|
|
|
|
type FeedUpdated struct {
|
|
Name string `json:"name"`
|
|
|
|
OccurredAt time.Time `json:"occurred_at"`
|
|
}
|