diff --git a/status.go b/status.go new file mode 100644 index 0000000000000000000000000000000000000000..4a79a9437f5957ed5e1074cc308b5634232618fe --- /dev/null +++ b/status.go @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: Amolith +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +package lunatask + +import ( + "errors" + "fmt" + "strings" +) + +// Errors returned by TaskStatus operations. +var ( + // ErrInvalidTaskStatus is returned when parsing an unknown task status string. + ErrInvalidTaskStatus = errors.New("invalid task status") +) + +// ParseTaskStatus parses a string to a TaskStatus value (case-insensitive). +// Valid values: "later", "next", "started", "waiting", "completed". +func ParseTaskStatus(str string) (TaskStatus, error) { + switch strings.ToLower(str) { + case "later": + return StatusLater, nil + case "next": + return StatusNext, nil + case "started": + return StatusStarted, nil + case "waiting": + return StatusWaiting, nil + case "completed": + return StatusCompleted, nil + default: + return "", fmt.Errorf("%w: %q", ErrInvalidTaskStatus, str) + } +} diff --git a/status_test.go b/status_test.go new file mode 100644 index 0000000000000000000000000000000000000000..46aafffc3ba9075c17505ca70a81a80c0813f4fe --- /dev/null +++ b/status_test.go @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: Amolith +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +package lunatask_test + +import ( + "testing" + + lunatask "git.secluded.site/go-lunatask" +) + +func TestParseTaskStatus(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + input string + want lunatask.TaskStatus + wantErr bool + }{ + {"later_lower", "later", lunatask.StatusLater, false}, + {"later_upper", "LATER", lunatask.StatusLater, false}, + {"later_mixed", "LaTeR", lunatask.StatusLater, false}, + {"next_lower", "next", lunatask.StatusNext, false}, + {"next_upper", "NEXT", lunatask.StatusNext, false}, + {"started_lower", "started", lunatask.StatusStarted, false}, + {"started_upper", "STARTED", lunatask.StatusStarted, false}, + {"waiting_lower", "waiting", lunatask.StatusWaiting, false}, + {"waiting_upper", "WAITING", lunatask.StatusWaiting, false}, + {"completed_lower", "completed", lunatask.StatusCompleted, false}, + {"completed_upper", "COMPLETED", lunatask.StatusCompleted, false}, + {"completed_mixed", "CoMpLeTeD", lunatask.StatusCompleted, false}, + {"invalid", "invalid", "", true}, + {"empty", "", "", true}, + {"numeric", "1", "", true}, + {"typo", "completd", "", true}, + } + + for _, testCase := range tests { + t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + + got, err := lunatask.ParseTaskStatus(testCase.input) + if (err != nil) != testCase.wantErr { + t.Errorf("ParseTaskStatus(%q) error = %v, wantErr %v", testCase.input, err, testCase.wantErr) + + return + } + + if !testCase.wantErr && got != testCase.want { + t.Errorf("ParseTaskStatus(%q) = %q, want %q", testCase.input, got, testCase.want) + } + }) + } +}