diff --git a/todo.go b/todo.go index 0cbf1ea..052f296 100644 --- a/todo.go +++ b/todo.go @@ -1,6 +1,7 @@ package todotxt import ( + "encoding/json" "fmt" "regexp" "sort" @@ -37,6 +38,82 @@ type Todo struct { Completed bool `json:"completed"` } +func (t Todo) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Id int `json:"id"` // Internal todo id. + Original string `json:"original"` // Original raw todo text. + Todo string `json:"todo"` // Todo part of todo text. + Priority string `json:"priority"` + Projects []string `json:"projects"` + Contexts []string `json:"contexts"` + AdditionalTags map[string]string `json:"additionalTags"` // Addon tags will be available here. + CreatedDate string `json:"createdDate"` + DueDate string `json:"dueDate"` + CompletedDate string `json:"completedDate"` + Completed bool `json:"completed"` + }{ + Id: t.Id, + Original: t.Original, + Todo: t.Todo, + Priority: t.Priority, + Projects: t.Projects, + Contexts: t.Contexts, + AdditionalTags: t.AdditionalTags, + CreatedDate: t.CreatedDate.Format(DateLayout), + DueDate: t.DueDate.Format(DateLayout), + CompletedDate: t.CompletedDate.Format(DateLayout), + Completed: t.Completed, + }) +} + +func (t *Todo) UnmarshalJSON(data []byte) error { + type jsonTodo struct { + Id int `json:"id"` // Internal todo id. + Original string `json:"original"` // Original raw todo text. + Todo string `json:"todo"` // Todo part of todo text. + Priority string `json:"priority"` + Projects []string `json:"projects"` + Contexts []string `json:"contexts"` + AdditionalTags map[string]string `json:"additionalTags"` // Addon tags will be available here. + CreatedDate string `json:"createdDate"` + DueDate string `json:"dueDate"` + CompletedDate string `json:"completedDate"` + Completed bool `json:"completed"` + } + j := jsonTodo{} + if err := json.Unmarshal(data, &j); err != nil { + return err + } + var err error + t.Id = j.Id + t.Original = j.Original + t.Todo = j.Todo + t.Priority = j.Priority + t.Projects = j.Projects + t.Contexts = j.Contexts + t.AdditionalTags = j.AdditionalTags + if j.CreatedDate != "" { + t.CreatedDate, err = time.Parse(DateLayout, j.CreatedDate) + if err != nil { + return err + } + } + if j.DueDate != "" { + t.DueDate, err = time.Parse(DateLayout, j.DueDate) + if err != nil { + return err + } + } + if j.CompletedDate != "" { + t.CompletedDate, err = time.Parse(DateLayout, j.CompletedDate) + if err != nil { + return err + } + } + t.Completed = j.Completed + return nil +} + // String returns a complete todo string in todo.txt format. // // Contexts, Projects and additional tags are alphabetically sorted,