package storage import ( "donniemarko/internal/note" "fmt" "strings" ) type Storage interface { GetAll() []*note.Note Get(id string) (*note.Note, error) Create(n *note.Note) error Delete(id string) Update(id string, n *note.Note) Search(query string) []*note.Note Count() int AddTag(noteID, tag string) error RemoveTag(noteID, tag string) error GetTags(noteID string) []string } type NoteStorage struct { Index map[string]*note.Note } func NewNoteStorage() *NoteStorage { return &NoteStorage{Index: make(map[string]*note.Note)} } // GetAll returns all notes stored in the index func (ns *NoteStorage) GetAll() []*note.Note { var notes []*note.Note for _, value := range ns.Index { notes = append(notes, value) } return notes } func (ns *NoteStorage) Get(id string) (*note.Note, error) { n, ok := ns.Index[id] if ok { return n, nil } return nil, fmt.Errorf("No note with id '%s'", id) } func (ns *NoteStorage) Create(n *note.Note) error { ns.Index[n.ID] = n return nil } func (ns *NoteStorage) Count() int { return len(ns.Index) } func (ns *NoteStorage) Delete(id string) { delete(ns.Index, id) } func (ns *NoteStorage) Update(id string, n *note.Note) { ns.Index[id] = n } func (ns *NoteStorage) Search(query string) []*note.Note { results := []*note.Note{} for _, note := range ns.Index { lowContent := strings.ToLower(string(note.Content)) lowQuery := strings.ToLower(query) if strings.Contains(lowContent, lowQuery) { results = append(results, note) } } return results } func (ns *NoteStorage) AddTag(noteID, tag string) error { n, ok := ns.Index[noteID] if !ok { return fmt.Errorf("No note with id '%s'", noteID) } for _, existing := range n.Tags { if existing == tag { return nil } } n.Tags = append(n.Tags, tag) return nil } func (ns *NoteStorage) RemoveTag(noteID, tag string) error { n, ok := ns.Index[noteID] if !ok { return fmt.Errorf("No note with id '%s'", noteID) } updated := n.Tags[:0] for _, existing := range n.Tags { if existing != tag { updated = append(updated, existing) } } n.Tags = updated return nil } func (ns *NoteStorage) GetTags(noteID string) []string { n, ok := ns.Index[noteID] if !ok { return []string{} } tags := make([]string, len(n.Tags)) copy(tags, n.Tags) return tags }