Add Provider interface

This commit is contained in:
Sasha Koshka 2024-12-09 22:57:59 -05:00
parent 952ce8f184
commit 433a112875
4 changed files with 18 additions and 10 deletions

View File

@ -76,7 +76,7 @@ func main () {
// set up the environment
environment := step.Environment { }
environment.FuncProviders = providers.All()
environment.Providers = providers.All()
err = environment.Init(context.Background())
if err != nil { log.Fatal(err) }

View File

@ -19,9 +19,10 @@ type Environment struct {
// FS, if specified, is the filesystem that this environment will load
// documents from. Its methods must be safe for concurrent execution.
FS fs.FS
// FuncProviders is a slice of FuncMap providers whoose functions will
// be available to any documents this environment processes.
FuncProviders []FuncProvider
// Providers is a slice of objects which can provide various
// functionality to the environment. In order to be used, values in this
// slice must implement one or more of the interfaces in provider.go.
Providers []Provider
documents usync.Locker[map[string] *Document]
funcMap template.FuncMap
@ -31,7 +32,9 @@ type Environment struct {
func (this *Environment) Init (ctx context.Context) error {
this.documents = usync.NewLocker(make(map[string] *Document))
this.funcMap = make(template.FuncMap)
for _, provider := range this.FuncProviders {
for _, provider := range this.Providers {
provider, ok := provider.(FuncProvider)
if !ok { continue }
funcMap := provider.FuncMap()
if funcMap == nil { continue }
for name, function := range funcMap {
@ -127,7 +130,7 @@ func (this *Environment) parse (name string, modTime time.Time, input io.Reader)
for name, function := range this.funcMap {
funcMap[name] = function
}
for _, provider := range this.FuncProviders {
for _, provider := range this.Providers {
provider, ok := provider.(FuncProviderFor)
if !ok { continue }
funcMapFor := provider.FuncMapFor(document)

View File

@ -2,8 +2,12 @@ package step
import "html/template"
// Provider is an object which provides extra functionality to an environment.
type Provider any
// FuncProvider provides a template.FuncMap.
type FuncProvider interface {
Provider
// FuncMap provides a template.FuncMap. It may return nil, in which case
// its result is simply not considered.
FuncMap () template.FuncMap
@ -12,7 +16,7 @@ type FuncProvider interface {
// FuncProviderFor is an object that provides a template.FuncMap for a specific
// document.
type FuncProviderFor interface {
FuncProvider
Provider
// FuncMap provides a template.FuncMap, given a particular document. It
// may return nil, in which case its result is simply not considered.
FuncMapFor (*Document) template.FuncMap
@ -20,6 +24,7 @@ type FuncProviderFor interface {
// Configurable is an object that can be configured according to metadata.
type Configurable interface {
Provider
// Configure uses config to configure the object. It must not modify
// config. Keys are namespaced with a '.' and are written in kebab case.
Configure (config Meta) error

View File

@ -1,6 +1,6 @@
package providers
import "git.tebibyte.media/sashakoshka/step"
import "git.tebibyte.media/sashakoshka/step"
import fpos "git.tebibyte.media/sashakoshka/step/providers/os"
import fphttp "git.tebibyte.media/sashakoshka/step/providers/http"
import fppath "git.tebibyte.media/sashakoshka/step/providers/path"
@ -11,8 +11,8 @@ import fpimport "git.tebibyte.media/sashakoshka/step/providers/import"
import fpmarkdown "git.tebibyte.media/sashakoshka/step/providers/markdown"
// All returns a slice of all providers defined in sub-packages.
func All () []step.FuncProvider {
return []step.FuncProvider {
func All () []step.Provider {
return []step.Provider {
new(fpos.Provider),
new(fphttp.Provider),
new(fppath.Provider),