/
blogposts.go
79 lines (66 loc) · 1.51 KB
/
blogposts.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package blogposts
import (
"bufio"
"bytes"
"fmt"
"io"
"io/fs"
"strings"
"testing/fstest"
)
type Post struct {
Title string
Description string
Tags []string
Body string
}
func NewPostsFromFs(fileSystem fstest.MapFS) ([]Post, error) {
dir, err := fs.ReadDir(fileSystem, ".")
if err != nil {
return nil, err
}
var posts []Post
for _, f := range dir {
post, err := getPost(fileSystem, f)
if err != nil {
return nil, err
}
posts = append(posts, post)
}
return posts, nil
}
func getPost(fileSystem fs.FS, f fs.DirEntry) (Post, error) {
postFile, err := fileSystem.Open(f.Name())
if err != nil {
return Post{}, err
}
defer postFile.Close()
return newPost(postFile)
}
const (
titleSeparator = "Title: "
descriptionSeparator = "Description: "
tagSeparator = "Tags: "
)
func newPost(postFile io.Reader) (Post, error) {
scanner := bufio.NewScanner(postFile)
readMetaLine := func(tagName string) string {
scanner.Scan()
return strings.TrimPrefix(scanner.Text(), tagName)
}
title := readMetaLine(titleSeparator)
description := readMetaLine(descriptionSeparator)
tags := strings.Split(readMetaLine(tagSeparator), ",")
body := readBody(scanner)
post := Post{Title: title, Description: description, Tags: tags, Body: body}
return post, nil
}
func readBody(scanner *bufio.Scanner) string {
scanner.Scan()
buffer := bytes.Buffer{}
for scanner.Scan() {
fmt.Fprintln(&buffer, scanner.Text())
}
body := strings.TrimSuffix(buffer.String(), "\n")
return body
}