inmem.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package todosvc
  2. import (
  3. "errors"
  4. "sync"
  5. "golang.org/x/net/context"
  6. )
  7. func NewInmemTodo() Todo {
  8. idsrc := make(chan ID)
  9. go func() {
  10. var i ID = 23
  11. for {
  12. idsrc <- i
  13. i += 1
  14. }
  15. }()
  16. return inmem{
  17. idsrc: idsrc,
  18. store: make(map[ID]Item),
  19. }
  20. }
  21. var ErrNotFound = errors.New("todo: not found")
  22. type inmem struct {
  23. idsrc <-chan ID
  24. mu sync.RWMutex
  25. store map[ID]Item
  26. }
  27. func (t inmem) Add(_ context.Context, title string) (ID, error) {
  28. t.mu.Lock()
  29. defer t.mu.Unlock()
  30. id := <-t.idsrc
  31. t.store[id] = Item{
  32. ID: id,
  33. Title: title,
  34. }
  35. return id, nil
  36. }
  37. func (t inmem) List(context.Context) ([]Item, error) {
  38. t.mu.RLock()
  39. defer t.mu.RUnlock()
  40. var items []Item
  41. for _, v := range t.store {
  42. items = append(items, v)
  43. }
  44. return items, nil
  45. }
  46. func (t inmem) Toggle(_ context.Context, id ID) error {
  47. t.mu.Lock()
  48. defer t.mu.Unlock()
  49. i, ok := t.store[id]
  50. if !ok {
  51. return ErrNotFound
  52. }
  53. i.Complete = !i.Complete
  54. t.store[id] = i
  55. return nil
  56. }
  57. func (t inmem) Delete(_ context.Context, id ID) error {
  58. t.mu.Lock()
  59. defer t.mu.Unlock()
  60. _, ok := t.store[id]
  61. if !ok {
  62. return ErrNotFound
  63. }
  64. delete(t.store, id)
  65. return nil
  66. }