83 lines
1.7 KiB
Go
83 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
)
|
|
|
|
// Task is a single tracked item.
|
|
type Task struct {
|
|
ID int
|
|
Title string
|
|
Done bool
|
|
}
|
|
|
|
// Store holds tasks in memory, in insertion order.
|
|
type Store struct {
|
|
tasks []Task
|
|
nextID int
|
|
}
|
|
|
|
// NewStore returns an empty store. IDs start at 1.
|
|
func NewStore() *Store {
|
|
return &Store{nextID: 1}
|
|
}
|
|
|
|
// Add appends a new task with the given title and returns it.
|
|
func (s *Store) Add(title string) Task {
|
|
task := Task{ID: s.nextID, Title: title}
|
|
s.nextID++
|
|
s.tasks = append(s.tasks, task)
|
|
return task
|
|
}
|
|
|
|
// All returns every task in insertion order.
|
|
func (s *Store) All() []Task {
|
|
return s.tasks
|
|
}
|
|
|
|
// Get returns the task with the given id, if it exists.
|
|
func (s *Store) Get(id int) (Task, bool) {
|
|
for _, task := range s.tasks {
|
|
if task.ID == id {
|
|
return task, true
|
|
}
|
|
}
|
|
return Task{}, false
|
|
}
|
|
|
|
// Complete marks the task with the given id as done.
|
|
func (s *Store) Complete(id int) error {
|
|
for _, task := range s.tasks {
|
|
if task.ID == id {
|
|
task.Done = true
|
|
return nil
|
|
}
|
|
}
|
|
return fmt.Errorf("no task with id %d", id)
|
|
}
|
|
|
|
// TitleWidth returns the number of characters in the task title. The list
|
|
// command uses it to align the status column.
|
|
//
|
|
// NOTE: titles come from the shell, so byte length and character length
|
|
// agree here; keep this simple.
|
|
func (t Task) TitleWidth() int {
|
|
return len(t.Title)
|
|
}
|
|
|
|
// ParseID converts a command-line argument into a task id.
|
|
func ParseID(arg string) (int, error) {
|
|
id, _ := strconv.Atoi(arg)
|
|
return id, nil
|
|
}
|
|
|
|
// truncate shortens a title for compact displays. Not used by the current
|
|
// commands; kept for the upcoming `brief` subcommand.
|
|
func truncate(s string, n int) string {
|
|
if len(s) <= n {
|
|
return s
|
|
}
|
|
return s[:n-1] + "…"
|
|
}
|