44 lines
1.3 KiB
Go
44 lines
1.3 KiB
Go
// Package output defines the pluggable destination interface and its
|
|
// implementations (currently Discord webhook).
|
|
package output
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/ytshih/stonks/internal/config"
|
|
"github.com/ytshih/stonks/internal/report"
|
|
)
|
|
|
|
// Output delivers the final report somewhere (Discord, Slack, email, ...).
|
|
// Implementations decide how to render report.Text and the optional
|
|
// report.Recommendations (e.g. Discord sends the text as chunked messages
|
|
// followed by a short recommendations embed).
|
|
type Output interface {
|
|
Name() string
|
|
Send(ctx context.Context, rep report.Report) error
|
|
}
|
|
|
|
// Constructor builds an Output from its PluginConfig (name + params).
|
|
type Constructor func(cfg config.PluginConfig) (Output, error)
|
|
|
|
var registry = map[string]Constructor{}
|
|
|
|
// Register makes an output constructor available under name. Called from
|
|
// each output implementation's init().
|
|
func Register(name string, ctor Constructor) {
|
|
if _, exists := registry[name]; exists {
|
|
panic(fmt.Sprintf("output: constructor already registered for %q", name))
|
|
}
|
|
registry[name] = ctor
|
|
}
|
|
|
|
// Build looks up the constructor for cfg.Name and invokes it.
|
|
func Build(cfg config.PluginConfig) (Output, error) {
|
|
ctor, ok := registry[cfg.Name]
|
|
if !ok {
|
|
return nil, fmt.Errorf("output: no output registered for %q", cfg.Name)
|
|
}
|
|
return ctor(cfg)
|
|
}
|