@@ -4,7 +4,11 @@
package lunatask
-import "fmt"
+import (
+ "errors"
+ "fmt"
+ "strings"
+)
// Eisenhower represents a quadrant in the Eisenhower priority matrix, which
// categorizes tasks by whether they are urgent (time-sensitive) and/or
@@ -77,3 +81,29 @@ func (e Eisenhower) IsUrgent() bool {
func (e Eisenhower) IsImportant() bool {
return e == EisenhowerDoNow || e == EisenhowerDoLater
}
+
+// Errors returned by Eisenhower operations.
+var (
+ // ErrInvalidEisenhower is returned when parsing an unknown Eisenhower quadrant string.
+ ErrInvalidEisenhower = errors.New("invalid eisenhower quadrant")
+)
+
+// ParseEisenhower parses a string to an Eisenhower quadrant value (case-insensitive).
+// Valid values: "uncategorized", "do-now", "delegate", "do-later", "eliminate",
+// as well as numeric strings "0" through "4".
+func ParseEisenhower(str string) (Eisenhower, error) {
+ switch strings.ToLower(str) {
+ case "uncategorized", "0":
+ return EisenhowerUncategorized, nil
+ case "do-now", "donow", "1":
+ return EisenhowerDoNow, nil
+ case "delegate", "2":
+ return EisenhowerDelegate, nil
+ case "do-later", "dolater", "3":
+ return EisenhowerDoLater, nil
+ case "eliminate", "4":
+ return EisenhowerEliminate, nil
+ default:
+ return 0, fmt.Errorf("%w: %q", ErrInvalidEisenhower, str)
+ }
+}
@@ -5,6 +5,7 @@
package lunatask_test
import (
+ "errors"
"testing"
lunatask "git.secluded.site/go-lunatask"
@@ -378,3 +379,71 @@ func TestTaskUpdateBuilder_WithEisenhowerTyped(t *testing.T) {
assertBodyFieldFloat(t, capture.Body, "eisenhower", 2)
}
+
+// --- ParseEisenhower ---
+
+func TestParseEisenhower(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ input string
+ want lunatask.Eisenhower
+ wantErr bool
+ }{
+ // Text values
+ {"uncategorized_lower", "uncategorized", lunatask.EisenhowerUncategorized, false},
+ {"uncategorized_upper", "UNCATEGORIZED", lunatask.EisenhowerUncategorized, false},
+ {"do_now_lower", "do-now", lunatask.EisenhowerDoNow, false},
+ {"do_now_upper", "DO-NOW", lunatask.EisenhowerDoNow, false},
+ {"donow_lower", "donow", lunatask.EisenhowerDoNow, false},
+ {"donow_upper", "DONOW", lunatask.EisenhowerDoNow, false},
+ {"delegate_lower", "delegate", lunatask.EisenhowerDelegate, false},
+ {"delegate_upper", "DELEGATE", lunatask.EisenhowerDelegate, false},
+ {"do_later_lower", "do-later", lunatask.EisenhowerDoLater, false},
+ {"do_later_upper", "DO-LATER", lunatask.EisenhowerDoLater, false},
+ {"dolater_lower", "dolater", lunatask.EisenhowerDoLater, false},
+ {"dolater_upper", "DOLATER", lunatask.EisenhowerDoLater, false},
+ {"eliminate_lower", "eliminate", lunatask.EisenhowerEliminate, false},
+ {"eliminate_upper", "ELIMINATE", lunatask.EisenhowerEliminate, false},
+
+ // Numeric values
+ {"zero", "0", lunatask.EisenhowerUncategorized, false},
+ {"one", "1", lunatask.EisenhowerDoNow, false},
+ {"two", "2", lunatask.EisenhowerDelegate, false},
+ {"three", "3", lunatask.EisenhowerDoLater, false},
+ {"four", "4", lunatask.EisenhowerEliminate, false},
+
+ // Invalid values
+ {"invalid", "invalid", 0, true},
+ {"empty", "", 0, true},
+ {"five", "5", 0, true},
+ {"negative", "-1", 0, true},
+ {"typo", "elimate", 0, true},
+ }
+
+ for _, testCase := range tests {
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+
+ got, err := lunatask.ParseEisenhower(testCase.input)
+ if (err != nil) != testCase.wantErr {
+ t.Errorf("ParseEisenhower(%q) error = %v, wantErr %v", testCase.input, err, testCase.wantErr)
+
+ return
+ }
+
+ if testCase.wantErr {
+ if !errors.Is(err, lunatask.ErrInvalidEisenhower) {
+ t.Errorf("ParseEisenhower(%q) error = %v, want ErrInvalidEisenhower", testCase.input, err)
+ }
+
+ return
+ }
+
+ if got != testCase.want {
+ t.Errorf("ParseEisenhower(%q) = %v, want %v", testCase.input, got, testCase.want)
+ }
+ })
+ }
+}