Files
swe-hiring/part3-taskcli/store.go
2026-07-06 06:00:10 +06:00

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] + "…"
}