package engine import ( "context" "fmt" "io" "sync" "gitoa.ru/go-4devs/templating/render" ) type Template interface { Name() string Execute(ctx context.Context, w io.Writer, data interface{}, param render.Params) error } func NewTemplates() Templates { return Templates{ list: make(map[string]Template), mu: &sync.RWMutex{}, } } type Templates struct { list map[string]Template mu *sync.RWMutex } func (t Templates) Get(_ context.Context, name string) (Template, error) { t.mu.RLock() defer t.mu.RUnlock() if tpl, ok := t.list[name]; ok { return tpl, nil } return nil, fmt.Errorf("templates get:%w", ErrNotFound) } func (t Templates) Set(_ context.Context, tpl Template) error { t.mu.Lock() defer t.mu.Unlock() if _, ok := t.list[tpl.Name()]; ok { return fmt.Errorf("templates set:%w", ErrDuplicate) } t.list[tpl.Name()] = tpl return nil } func (t Templates) List(_ context.Context) []Template { list := make([]Template, 0, len(t.list)) for _, tpl := range t.list { list = append(list, tpl) } return list } func NewTemplate(name string, execute func(w io.Writer, data interface{}) error) ExecTemplate { return ExecTemplate{ name: name, execute: execute, } } type ExecTemplate struct { name string execute func(w io.Writer, data interface{}) error } func (t ExecTemplate) Name() string { return t.name } func (t ExecTemplate) Execute(_ context.Context, w io.Writer, data interface{}, _ render.Params) error { return t.execute(w, data) }