diff --git a/internal/task/task.go b/internal/task/task.go index 9d3003f..a19f9b8 100644 --- a/internal/task/task.go +++ b/internal/task/task.go @@ -17,6 +17,7 @@ const ( FOLDER_INBOX = "INBOX" FOLDER_NEW = "New" + QUOTE_PREFIX = ">" FIELD_SEPARATOR = ":" FIELD_ID = "id" FIELD_ACTION = "action" @@ -50,19 +51,25 @@ type Task struct { // This enables updating a task by forwarding a topposted message whith new values for fields that the user wants to update. func New(msg *mstore.Message) *Task { dirty := false - id := FieldFromBody(FIELD_ID, msg.Body) + id, d := FieldFromBody(FIELD_ID, msg.Body) if id == "" { id = uuid.New().String() dirty = true } + if d { + dirty = true + } - action := FieldFromBody(FIELD_ACTION, msg.Body) + action, d := FieldFromBody(FIELD_ACTION, msg.Body) if action == "" { action = FieldFromSubject(FIELD_ACTION, msg.Subject) if action != "" { dirty = true } } + if d { + dirty = true + } folder := msg.Folder if folder == FOLDER_INBOX { @@ -111,19 +118,28 @@ func (t *Task) FormatBody() string { return body } -func FieldFromBody(field, body string) string { +func FieldFromBody(field, body string) (string, bool) { + value := "" + dirty := false + lines := strings.Split(body, "\n") for _, line := range lines { parts := strings.SplitN(line, FIELD_SEPARATOR, 2) if len(parts) < 2 { continue } - if strings.ToLower(strings.TrimSpace(parts[0])) == field { - return strings.TrimSpace(parts[1]) + + fieldName := strings.ToLower(strings.TrimSpace(strings.TrimPrefix(parts[0], QUOTE_PREFIX))) + if fieldName == field { + if value == "" { + value = strings.TrimSpace(parts[1]) + } else { + dirty = true + } } } - return "" + return value, dirty } func FieldFromSubject(field, subject string) string { diff --git a/internal/task/task_test.go b/internal/task/task_test.go index 38f79f8..077e350 100644 --- a/internal/task/task_test.go +++ b/internal/task/task_test.go @@ -69,6 +69,7 @@ id: %s action: %s `, id, action), }, + hasId: true, exp: &task.Task{ Id: id, Folder: folder, @@ -82,6 +83,27 @@ action: %s Subject: action, Body: fmt.Sprintf(`id: %s`, id), }, + hasId: true, + exp: &task.Task{ + Id: id, + Folder: folder, + Action: action, + Dirty: true, + }, + }, + { + name: "quoted fields", + message: &mstore.Message{ + Folder: folder, + Body: fmt.Sprintf(` +action: %s + +Forwarded message: +> id: %s +> action: old action + `, action, id), + }, + hasId: true, exp: &task.Task{ Id: id, Folder: folder, @@ -162,10 +184,11 @@ action: an action func TestFieldFromBody(t *testing.T) { for _, tc := range []struct { - name string - field string - body string - exp string + name string + field string + body string + expValue string + expDirty bool }{ { name: "empty field", @@ -190,7 +213,7 @@ fielda: valuea fieldb: valueb fieldc: valuec `, - exp: "valueb", + expValue: "valueb", }, { name: "present twice", @@ -199,29 +222,39 @@ fieldc: valuec field: valuea field: valueb `, - exp: "valuea", + expValue: "valuea", + expDirty: true, }, { - name: "with colons", - field: "field", - body: "field:: val:ue", - exp: ": val:ue", + name: "with colons", + field: "field", + body: "field:: val:ue", + expValue: ": val:ue", }, { name: "trim field", field: "field", body: " field : value", - exp: "value", + expValue: "value", }, { name: "trim value", field: "field", body: "field: value ", - exp: "value", + expValue: "value", + }, + { + name: "quoted", + + field: "field", + body: "> field: value", + expValue: "value", }, } { t.Run(tc.name, func(t *testing.T) { - test.Equals(t, tc.exp, task.FieldFromBody(tc.field, tc.body)) + actValue, actDirty := task.FieldFromBody(tc.field, tc.body) + test.Equals(t, tc.expValue, actValue) + test.Equals(t, tc.expDirty, actDirty) }) } }