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 }