moth/cmd/mothd/transpiler.go

82 lines
2.0 KiB
Go

package main
import (
"bytes"
"encoding/json"
"io"
"log"
"time"
"github.com/dirtbags/moth/pkg/transpile"
"github.com/spf13/afero"
)
// NewTranspilerProvider returns a new TranspilerProvider.
func NewTranspilerProvider(fs afero.Fs) TranspilerProvider {
return TranspilerProvider{fs}
}
// TranspilerProvider provides puzzles generated from source files on disk
type TranspilerProvider struct {
fs afero.Fs
}
// Inventory returns a Category list for this provider.
func (p TranspilerProvider) Inventory() []Category {
ret := make([]Category, 0)
inv, err := transpile.FsInventory(p.fs)
if err != nil {
log.Print(err)
return ret
}
for name, points := range inv {
ret = append(ret, Category{name, points})
}
return ret
}
type nopCloser struct {
io.ReadSeeker
}
func (c nopCloser) Close() error {
return nil
}
// Open returns a file associated with the given category and point value.
func (p TranspilerProvider) Open(cat string, points int, filename string) (ReadSeekCloser, time.Time, error) {
c := transpile.NewFsCategory(p.fs, cat)
switch filename {
case "", "puzzle.json":
p, err := c.Puzzle(points)
if err != nil {
return nopCloser{new(bytes.Reader)}, time.Time{}, err
}
jp, err := json.Marshal(p)
if err != nil {
return nopCloser{new(bytes.Reader)}, time.Time{}, err
}
return nopCloser{bytes.NewReader(jp)}, time.Now(), nil
default:
r, err := c.Open(points, filename)
return r, time.Now(), err
}
}
// CheckAnswer checks whether an answer si correct.
func (p TranspilerProvider) CheckAnswer(cat string, points int, answer string) (bool, error) {
c := transpile.NewFsCategory(p.fs, cat)
return c.Answer(points, answer), nil
}
// Mothball packages up a category into a mothball.
func (p TranspilerProvider) Mothball(cat string) (*bytes.Reader, error) {
c := transpile.NewFsCategory(p.fs, cat)
return transpile.Mothball(c)
}
// Maintain performs housekeeping.
func (p TranspilerProvider) Maintain(updateInterval time.Duration) {
// Nothing to do here.
}