go-by-test/blogposts/post.go

67 lines
1.4 KiB
Go
Raw Normal View History

package blogposts
import (
2024-09-24 19:26:42 +00:00
"bufio"
"io"
"io/fs"
2024-09-24 19:26:42 +00:00
"strings"
)
type Post struct {
Title, Description, Body string
Tags []string
}
2024-09-24 19:26:42 +00:00
const (
2024-09-24 19:38:21 +00:00
titleLine = "Title: "
descriptionLine = "Description: "
tagsLine = "Tags: "
2024-09-24 19:58:06 +00:00
tagSeparator = ", "
2024-09-24 19:51:09 +00:00
bodySeparator = "---"
2024-09-24 19:26:42 +00:00
)
func getPost(fileSystem fs.FS, fileName string) (Post, error) {
postFile, err := fileSystem.Open(fileName)
if err != nil {
return Post{}, err
}
defer postFile.Close()
return newPost(postFile)
}
// NOTE: Does newPost have to be coupled to an fs.File ?
// Do we use all the methods and data from this type? What do we really need?
func newPost(postFile io.Reader) (Post, error) {
2024-09-24 19:26:42 +00:00
scanner := bufio.NewScanner(postFile)
readMetaLine := func(tagName string) string {
scanner.Scan()
return strings.TrimPrefix(scanner.Text(), tagName)
}
2024-09-24 19:58:06 +00:00
post := Post{
Title: readMetaLine(titleLine),
Description: readMetaLine(descriptionLine),
Tags: strings.Split(readMetaLine(tagsLine), tagSeparator),
Body: readBody(scanner),
2024-09-24 19:38:21 +00:00
}
2024-09-24 19:58:06 +00:00
return post, nil
}
2024-09-24 19:38:21 +00:00
2024-09-24 19:58:06 +00:00
func readBody(scanner *bufio.Scanner) string {
2024-09-24 19:51:09 +00:00
for scanner.Scan() {
if strings.TrimSpace(scanner.Text()) == bodySeparator {
break
}
}
// The rest is the body
var buf strings.Builder
for scanner.Scan() {
buf.Write(scanner.Bytes())
buf.Write([]byte{'\n'})
}
2024-09-24 19:58:06 +00:00
return strings.TrimSuffix(buf.String(), "\n")
}