summaryrefslogtreecommitdiff
path: root/internal/store
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-10 23:11:30 +0300
committerPaul Buetow <paul@buetow.org>2026-04-10 23:11:30 +0300
commit65430e9876a32988839deb7a70dc1e42da21cf64 (patch)
treee0de040cb53d5b90587908f2d55e86e49664fc35 /internal/store
parent4b4b3665230faafbd994f09894cb07c8f9d4b359 (diff)
Release 0.28.2v0.28.2
Diffstat (limited to 'internal/store')
-rw-r--r--internal/store/store.go32
-rw-r--r--internal/store/store_test.go30
2 files changed, 57 insertions, 5 deletions
diff --git a/internal/store/store.go b/internal/store/store.go
index 16f50ba..daafb28 100644
--- a/internal/store/store.go
+++ b/internal/store/store.go
@@ -25,6 +25,13 @@ type CardStore struct {
outputDir string
}
+// CardDirectory describes one discovered on-disk card directory and the word
+// stored inside it.
+type CardDirectory struct {
+ Path string
+ Word string
+}
+
// New constructs a CardStore rooted at outputDir.
func New(outputDir string) *CardStore {
return &CardStore{outputDir: outputDir}
@@ -56,13 +63,26 @@ func (cs *CardStore) FindOrCreateCardDirectory(word string) string {
// candidate directory; pass nil to accept all directories that have a word
// file.
func (cs *CardStore) ScanWords(hasContent func(wordDir string) bool) []string {
+ cards := cs.ListCardDirectories(hasContent)
+ words := make([]string, 0, len(cards))
+ for _, card := range cards {
+ words = append(words, card.Word)
+ }
+ sort.Strings(words)
+ return words
+}
+
+// ListCardDirectories scans the output directory for non-hidden card
+// subdirectories that contain word metadata. The result is sorted by directory
+// path so callers can process cards in deterministic creation order.
+func (cs *CardStore) ListCardDirectories(hasContent func(wordDir string) bool) []CardDirectory {
entries, err := os.ReadDir(cs.outputDir)
if err != nil {
// Output directory does not exist yet; return empty list silently.
- return []string{}
+ return []CardDirectory{}
}
- words := make([]string, 0, len(entries))
+ cards := make([]CardDirectory, 0, len(entries))
for _, entry := range entries {
if !entry.IsDir() || strings.HasPrefix(entry.Name(), ".") {
@@ -77,12 +97,14 @@ func (cs *CardStore) ScanWords(hasContent func(wordDir string) bool) []string {
}
if hasContent == nil || hasContent(wordDir) {
- words = append(words, word)
+ cards = append(cards, CardDirectory{Path: wordDir, Word: word})
}
}
- sort.Strings(words)
- return words
+ sort.Slice(cards, func(i, j int) bool {
+ return cards[i].Path < cards[j].Path
+ })
+ return cards
}
// GenerateCardID creates a unique ID for a card based on the current timestamp
diff --git a/internal/store/store_test.go b/internal/store/store_test.go
index 6d34d0c..02da883 100644
--- a/internal/store/store_test.go
+++ b/internal/store/store_test.go
@@ -138,3 +138,33 @@ func TestCardStoreScanWords(t *testing.T) {
t.Errorf("ScanWords(nil) = %v; want 2 words", allWords)
}
}
+
+func TestCardStoreListCardDirectories(t *testing.T) {
+ tmpDir := t.TempDir()
+
+ makeCard := func(id, word string) string {
+ cardDir := filepath.Join(tmpDir, id)
+ _ = os.MkdirAll(cardDir, 0755)
+ _ = os.WriteFile(filepath.Join(cardDir, "word.txt"), []byte(word), 0644)
+ return cardDir
+ }
+
+ card2 := makeCard("card2", "куче")
+ makeCard("card1", "котка")
+ makeCard(".hidden", "hidden")
+
+ cs := store.New(tmpDir)
+ cards := cs.ListCardDirectories(func(wordDir string) bool {
+ return wordDir != card2
+ })
+
+ if len(cards) != 1 {
+ t.Fatalf("ListCardDirectories() returned %d cards, want 1", len(cards))
+ }
+ if cards[0].Word != "котка" {
+ t.Fatalf("ListCardDirectories()[0].Word = %q, want %q", cards[0].Word, "котка")
+ }
+ if filepath.Base(cards[0].Path) != "card1" {
+ t.Fatalf("ListCardDirectories()[0].Path = %q, want base %q", cards[0].Path, "card1")
+ }
+}