From 9827378121f1fc800171e84e4a9660615cb1f1db Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sun, 27 Oct 2024 21:50:28 +0200 Subject: add HasTag --- internal/entry/entry.go | 42 +++++++++++++++++++++++++++++++++++++----- internal/entry/entry_test.go | 22 ++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) (limited to 'internal') diff --git a/internal/entry/entry.go b/internal/entry/entry.go index ee73f42..1c5dbad 100644 --- a/internal/entry/entry.go +++ b/internal/entry/entry.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "regexp" + "slices" "strings" "time" @@ -16,16 +17,22 @@ type State int const ( Unknown State = iota + Inboxed // TODO: Implement Queued Posted ) -var ErrSizeLimitExceeded = errors.New("message size limit exceeded") +var ( + validTags = []string{"ask", "prio", "now"} + ErrSizeLimitExceeded = errors.New("message size limit exceeded") +) func (s State) String() string { switch s { case Unknown: return "unknown" + case Inboxed: + return "inboxed" case Queued: return "queued" case Posted: @@ -35,37 +42,55 @@ func (s State) String() string { } } +var Zero = Entry{} + type Entry struct { Path string Time time.Time State State + tags []string } func (e Entry) String() string { + if e.State == Inboxed { + return fmt.Sprintf("Path:%s;State:%s", e.Path, e.State) + } return fmt.Sprintf("Path:%s;Stamp:%s,State:%s", e.Path, e.Time.Format(timestamp.Format), e.State) } -var Zero = Entry{} - // filePath format: /foo/foobarbaz.something.here.txt.STAMP.{posted,queued} +// or for inboxed: /foo.txt +// or inboxed with tags: /foo.prio.ask.txt func New(filePath string) (Entry, error) { e := Entry{Path: filePath} // We want to get the STAMP! parts := strings.Split(filePath, ".") - if len(parts) < 4 { + if len(parts) < 2 { + // Could be 2 if inboxed return e, fmt.Errorf("not a valid entry path: %s", filePath) } + for _, part := range parts { + if slices.Contains(validTags, part) { + e.tags = append(e.tags, part) + } + } + switch parts[len(parts)-1] { case "queued": e.State = Queued case "posted": e.State = Posted default: - return e, fmt.Errorf("can't parse state from path: %s", filePath) + e.State = Inboxed + return e, nil } + if len(parts) < 4 { + // If not inboxed, must be longer. + return e, fmt.Errorf("not a valid entry path: %s", filePath) + } var err error if e.Time, err = timestamp.Parse(parts[len(parts)-2]); err != nil { return e, err @@ -106,6 +131,9 @@ func (e Entry) ContentWithLimit(sizeLimit int) (string, []string, error) { } func (e *Entry) MarkPosted() error { + if e.State == Inboxed { + return errors.New("entry still inboxed, can not mark as posted") + } if e.State != Queued { return errors.New("entry is not queued") } @@ -123,6 +151,10 @@ func (e *Entry) MarkPosted() error { return nil } +func (e Entry) HasTag(tag string) bool { + return slices.Contains(e.tags, tag) +} + func (e Entry) Edit() error { if err := prompt.EditFile(e.Path); err != nil { return err diff --git a/internal/entry/entry_test.go b/internal/entry/entry_test.go index 43c2243..c59dc16 100644 --- a/internal/entry/entry_test.go +++ b/internal/entry/entry_test.go @@ -80,6 +80,28 @@ func TestExtractURLs(t *testing.T) { } } +func TestHasTag(t *testing.T) { + // TODO: Remove t.Parallel() everywhere + table := map[string][]string{ + "foo.txt": []string{}, + "foo.prio.txt": []string{"prio"}, + "foo.ask.prio.txt": []string{"prio", "ask"}, + "prio.foo.ask.txt": []string{"prio", "ask"}, + } + + for fileName, expectedTags := range table { + ent, err := New(fileName) + if err != nil { + t.Error(err) + } + for _, tag := range expectedTags { + if !ent.HasTag(tag) { + t.Errorf("expected tag '%s' but got '%s'", tag, ent.tags) + } + } + } +} + func FuzzExtractURLs(f *testing.F) { f.Add("/path?myjfa=lwsr4imj&dgqeg=m3uwwsak") f.Add("/?amfbm=bwzqu46m&xheuh=nv588d98") -- cgit v1.2.3