package services import ( "errors" "io" "os" "path/filepath" "sync" "github.com/rs/zerolog/log" ) var ( ErrFileCreation = errors.New("unexpected error occurred while creating book file") ErrFileCopy = errors.New("unexpected error occurred while copying book file") ) type IStore interface { Save(name string, content io.ReadCloser) error } var _ IStore = (*BookStore)(nil) type BookStore struct { processing *sync.WaitGroup dir string } func NewBookStore(dir string) *BookStore { if err := os.MkdirAll(dir, 0755); err != nil { //nolint log.Fatal().Err(err).Msg("unable to create store dir") } return &BookStore{ processing: &sync.WaitGroup{}, dir: dir, } } func (bs *BookStore) Done() <-chan struct{} { chDone := make(chan struct{}) go func() { bs.processing.Wait() chDone <- struct{}{} log.Info().Msg("book store processing done") }() return chDone } func (bs *BookStore) Save(name string, content io.ReadCloser) error { bs.processing.Add(1) defer bs.processing.Done() defer content.Close() dst, err := os.Create(filepath.Join(GetEnv().GetDir(), name)) if err != nil { log.Err(err).Msg(ErrFileCreation.Error()) return ErrFileCreation } defer dst.Close() if _, err := io.Copy(dst, content); err != nil { log.Err(err).Msg(ErrFileCopy.Error()) return ErrFileCopy } return nil }