Skip to content

Commit a56bae4

Browse files
committed
Implement route to add words to dictionary
1 parent a3e2638 commit a56bae4

4 files changed

Lines changed: 83 additions & 4 deletions

File tree

internal/routes/dictionary_item.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package routes
2+
3+
import (
4+
"context"
5+
"errors"
6+
7+
"github.com/f1monkey/spellchecker-web/internal/spellchecker"
8+
"github.com/swaggest/usecase"
9+
"github.com/swaggest/usecase/status"
10+
)
11+
12+
type DictionaryItemAddRequest struct {
13+
Code string `path:"code" minLength:"1"`
14+
15+
Phrases []DictionaryItemPhrase `json:"phrases" minLength:"1"`
16+
}
17+
18+
type DictionaryItemPhrase struct {
19+
Text string `json:"text" description:"The word or phrase to be added to the dictionary."`
20+
Weight uint `json:"weight" min:"1" description:"A numeric value indicating the importance or influence of this entry in spellchecking or suggestions."`
21+
}
22+
23+
type DictionaryItemAddResponse struct {
24+
Words int `json:"words" description:"Number of phrases successfully added."`
25+
}
26+
27+
func dictionaryItemAdd(registry *spellchecker.Registry) usecase.Interactor {
28+
u := usecase.NewInteractor(func(ctx context.Context, input DictionaryItemAddRequest, output *DictionaryItemAddResponse) error {
29+
sc, err := registry.Get(input.Code)
30+
if errors.Is(spellchecker.ErrNotFound, err) {
31+
return status.Wrap(err, status.NotFound)
32+
} else if err != nil {
33+
return status.Wrap(err, status.Internal)
34+
}
35+
36+
wordCnt := 0
37+
38+
for i := range input.Phrases {
39+
40+
words := wordSymbols.FindAllString(input.Phrases[i].Text, -1)
41+
if len(words) == 0 {
42+
continue
43+
}
44+
45+
weight := input.Phrases[i].Weight
46+
if weight == 0 {
47+
weight = 1
48+
}
49+
50+
sc.AddWeight(weight, words...)
51+
wordCnt += len(words)
52+
}
53+
54+
output.Words = wordCnt
55+
56+
return nil
57+
})
58+
59+
u.SetTitle("Add phrases/words to spellchecker")
60+
u.SetDescription("Adds one or more custom phrases or words to the spellchecker dictionary. Each phrase can have an optional weight to influence matching or prioritization.")
61+
u.SetExpectedErrors(status.Internal)
62+
63+
return u
64+
}

internal/routes/routes.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,9 @@ func dictionaryRoutes(registry *spellchecker.Registry) func(r chi.Router) {
2929
r.Method(http.MethodPost, "/{code}/save", nethttp.NewHandler(
3030
dictionarySave(registry)),
3131
)
32+
33+
r.Method(http.MethodPost, "/{code}/add", nethttp.NewHandler(
34+
dictionaryItemAdd(registry)),
35+
)
3236
}
3337
}

internal/spellchecker/registry.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,16 @@ func (r *Registry) Add(code string, options Options) (*spellchecker.Spellchecker
110110
return result, nil
111111
}
112112

113-
func (r *Registry) Get(code string) *spellchecker.Spellchecker {
113+
func (r *Registry) Get(code string) (*spellchecker.Spellchecker, error) {
114114
r.mu.RLock()
115115
defer r.mu.RUnlock()
116116

117-
return r.items[code].Spellchecker
117+
v, ok := r.items[code]
118+
if !ok {
119+
return nil, ErrNotFound
120+
}
121+
122+
return v.Spellchecker, nil
118123
}
119124

120125
func (r *Registry) Delete(code string) error {

internal/spellchecker/registry_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,21 @@ func Test_Registry_Get(t *testing.T) {
148148
_, err = r.Add("code", Options{Alphabet: "abc"})
149149
require.NoError(t, err)
150150

151-
require.NotNil(t, r.Get("code"))
151+
v, err := r.Get("code")
152+
require.NoError(t, err)
153+
154+
require.NotNil(t, v)
152155
})
153156

154157
t.Run("not found", func(t *testing.T) {
155158
t.Parallel()
156159

157160
r, err := NewRegistry(context.Background(), t.TempDir())
158161
require.NoError(t, err)
159-
require.Nil(t, r.Get("code"))
162+
163+
v, err := r.Get("code")
164+
require.ErrorIs(t, err, ErrNotFound)
165+
require.Nil(t, v)
160166
})
161167
}
162168

0 commit comments

Comments
 (0)