home/internal/entry/repository/memory/memory_entry.go

74 lines
1.7 KiB
Go

package memory
import (
"context"
"errors"
"fmt"
"io/fs"
"sync"
"testing/fstest"
"github.com/adrg/frontmatter"
"gopkg.in/yaml.v2"
"source.toby3d.me/toby3d/home/internal/domain"
"source.toby3d.me/toby3d/home/internal/entry"
)
type (
Page struct {
Title string `yaml:"title"`
Description string `yaml:"description"`
Params map[string]any `yaml:",inline"`
Content []byte `yaml:"-"`
}
memoryEntryRepository struct {
mutex *sync.RWMutex
files fstest.MapFS
}
)
var FrontMatterFormats = []*frontmatter.Format{
frontmatter.NewFormat(`---`, `---`, yaml.Unmarshal),
}
func (repo *memoryEntryRepository) Get(_ context.Context, lang domain.Language, p string) (*domain.Entry, error) {
f, err := repo.files.Open(p)
if err != nil {
return nil, fmt.Errorf("cannot get entry from memory: %w", err)
}
defer f.Close()
data := &Page{
Params: make(map[string]any),
}
if data.Content, err = frontmatter.Parse(f, data, FrontMatterFormats...); err != nil {
return nil, fmt.Errorf("cannot parse entry content as FrontMatter: %w", err)
}
return &domain.Entry{
File: domain.NewPath(p),
Language: lang,
Title: data.Title,
Content: data.Content,
Description: data.Description,
Params: data.Params,
Resources: make([]*domain.Resource, 0),
Translations: make([]*domain.Entry, 0),
}, nil
}
func (repo *memoryEntryRepository) Stat(_ context.Context, l domain.Language, p string) (bool, error) {
_, err := fs.Stat(repo.files, p)
return errors.Is(err, fs.ErrExist), nil
}
func NewMemoryEntryRepository(files fstest.MapFS) entry.Repository {
return &memoryEntryRepository{
mutex: new(sync.RWMutex),
files: files,
}
}