From 69af7eaee3e81e30d1f1941f4ac873545964dd92 Mon Sep 17 00:00:00 2001 From: Kirillkriv Date: Fri, 21 Aug 2026 15:27:37 +0500 Subject: [PATCH] feat: import interface --- internal/adapters/importer/importer.go | 43 ++++++++++++++++++++++++++ internal/application/application.go | 22 +++++++++++++ internal/controllers/cli/cli.go | 1 + 3 files changed, 66 insertions(+) create mode 100644 internal/adapters/importer/importer.go diff --git a/internal/adapters/importer/importer.go b/internal/adapters/importer/importer.go new file mode 100644 index 0000000..f7b4ede --- /dev/null +++ b/internal/adapters/importer/importer.go @@ -0,0 +1,43 @@ +package importer + +import ( + "context" + "fmt" + "github.com/abelith/spellbook/internal/models" + "io" + "sync" +) + +type Importer interface { + Import(ctx context.Context, r io.Reader) (<-chan models.Spell, <-chan error, error) +} + +var ( + importers = make(map[string]Importer) + mu sync.Mutex +) + +func Register(name string, imp Importer) { + mu.Lock() + defer mu.Unlock() + + if imp == nil { + panic("importer: Importer cannot be nil") + } + if _, ok := importers[name]; ok { + panic("importer: Register called twice for " + name) + } + importers[name] = imp +} + +func Import(ctx context.Context, name string, r io.Reader) (<-chan models.Spell, <-chan error, error) { + mu.Lock() + imp, ok := importers[name] + mu.Unlock() + + if !ok { + return nil, nil, fmt.Errorf("importer %s not found", name) + } + + return imp.Import(ctx, r) +} diff --git a/internal/application/application.go b/internal/application/application.go index 2c4c85c..c5928d4 100644 --- a/internal/application/application.go +++ b/internal/application/application.go @@ -3,6 +3,7 @@ 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" ) @@ -93,3 +94,24 @@ func (a *Application) ExportSpells( return nil } + +func (a *Application) ImportSpells( + ctx context.Context, + name string, + r io.Reader, +) error { + ch, errCh, err := importer.Import(ctx, name, r) + if err != nil { + return err + } + + if err := a.spellCmd.Import(ctx, ch); err != nil { + return err + } + + if err := <-errCh; err != nil { + return err + } + + return nil +} diff --git a/internal/controllers/cli/cli.go b/internal/controllers/cli/cli.go index bde69c4..ea830ab 100644 --- a/internal/controllers/cli/cli.go +++ b/internal/controllers/cli/cli.go @@ -14,6 +14,7 @@ type Application interface { DeleteSpell(ctx context.Context, spellName string) error CastSpell(ctx context.Context, spellCast models.SpellCast) (models.CastResult, error) ExportSpells(ctx context.Context, exp string, w io.Writer) error + ImportSpells(ctx context.Context, exp string, r io.Reader) error } type CLI struct {