Files
spellbook/internal/application/application.go
2026-08-21 15:48:02 +05:00

123 lines
2.4 KiB
Go

package application
import (
"context"
"github.com/abelith/spellbook/internal/adapters/exporter"
"github.com/abelith/spellbook/internal/adapters/importer"
"github.com/abelith/spellbook/internal/models"
"io"
)
type SpellCaster interface {
Cast(ctx context.Context, cast models.SpellCast) (models.CastResult, error)
}
type SpellCommand interface {
Add(ctx context.Context, spell models.Spell) error
Delete(ctx context.Context, spellName string) error
Import(ctx context.Context, ch <-chan models.Spell) error
}
type SpellQuery interface {
Get(ctx context.Context, spellName string) (models.Spell, error)
GetMany(ctx context.Context, query models.SearchQuery) ([]models.Spell, error)
Count(ctx context.Context) (int, error)
Export(ctx context.Context) (<-chan models.Spell, <-chan error, error)
}
type Application struct {
caster SpellCaster
spellCmd SpellCommand
spellQuery SpellQuery
}
func NewApplication(caster SpellCaster, cmd SpellCommand, query SpellQuery) *Application {
return &Application{
caster: caster,
spellCmd: cmd,
spellQuery: query,
}
}
func (a *Application) AddSpell(
ctx context.Context,
spell models.Spell,
) error {
return a.spellCmd.Add(ctx, spell)
}
func (a *Application) GetSpell(
ctx context.Context,
spellName string,
) (models.Spell, error) {
return a.spellQuery.Get(ctx, spellName)
}
func (a *Application) GetSpells(
ctx context.Context,
query models.SearchQuery,
) ([]models.Spell, error) {
return a.spellQuery.GetMany(ctx, query)
}
func (a *Application) DeleteSpell(
ctx context.Context,
spellName string,
) error {
return a.spellCmd.Delete(ctx, spellName)
}
func (a *Application) CastSpell(
ctx context.Context,
spellCast models.SpellCast,
) (models.CastResult, error) {
return a.caster.Cast(ctx, spellCast)
}
func (a *Application) ExportSpells(
ctx context.Context,
name string,
w io.Writer,
) error {
ch, errCh, err := a.spellQuery.Export(ctx)
if err != nil {
return err
}
if err := exporter.Export(ctx, name, ch, w); err != nil {
return err
}
if err := <-errCh; err != nil {
return err
}
return nil
}
func (a *Application) ImportSpells(
ctx context.Context,
name string,
r io.Reader,
) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
ch, errCh, err := importer.Import(ctx, name, r)
if err != nil {
cancel()
return err
}
if err := a.spellCmd.Import(ctx, ch); err != nil {
cancel()
return err
}
if err := <-errCh; err != nil {
return err
}
return nil
}