package task import ( "errors" "local/todo-server/server/ajax/form" "net/http" "regexp" "strings" "time" "github.com/google/uuid" ) type Task struct { ID string UUID string Title string Priority int Tags []string Created time.Time Edited time.Time Completed time.Time Complete bool Note []string Due time.Time } func New(r *http.Request) (*Task, error) { task := &Task{ UUID: uuid.New().String(), Title: form.Get(r, "title"), Priority: form.ToInt(form.Get(r, "prio")), Tags: form.ToStrArr(form.Get(r, "tags")), Created: time.Now(), Edited: time.Now(), Due: form.ToTime(form.Get(r, "duedate")), } task.ID = task.UUID task.SetNote(form.Get(r, "note")) return task, task.validate() } func (t *Task) AppendTags(tags []string) { t.touch() t.Tags = append(t.Tags, tags...) } func (t *Task) SetComplete(state bool) { t.touch() t.Complete = state if t.Complete { t.Completed = time.Now() } else { t.Completed = time.Time{} } } func (t *Task) SetPrio(prio int) { t.touch() t.Priority = prio } func (t *Task) SetNote(note string) { t.touch() t.Note = strings.Split(note, "\n") } func (t *Task) touch() { t.Edited = time.Now() } func (t *Task) validate() error { if t.Title == "" { return errors.New("task cannot have nil title") } if err := t.smartSyntax(); err != nil { return err } return nil } func (t *Task) smartSyntax() error { re := regexp.MustCompile(`^(/([+-]{0,1}\d+)?/)?(.*?)(\s+/([^/]*)/$)?$|`) matches := re.FindAllStringSubmatch(t.Title, 1)[0] if len(matches) != 6 { return nil } if matches[1] != "" { t.Priority = form.ToInt(matches[1]) } if matches[3] != "" { t.Title = matches[3] } if matches[5] != "" { t.Tags = form.ToStrArr(matches[5]) } return nil }