Compare commits

...
5 Commits
Author SHA1 Message Date
simonkellet 0b27242338 added saving to a file and cleaned up magic numbers 2023-08-16 15:46:37 +01:00
simonkellet a66f30b663 added go.sum file 2023-08-16 15:46:17 +01:00
simonkellet 5ab7eb6e0b fixes 2023-08-15 14:25:58 +01:00
simonkellet 694b4c2cdb more features! 2023-08-15 14:22:19 +01:00
simonkellet d08834e39e split the todo into a sep file 2023-08-15 14:22:01 +01:00
5 changed files with 191 additions and 64 deletions
+7
View File
@@ -1,3 +1,10 @@
module todo-app module todo-app
go 1.20 go 1.20
require (
github.com/fatih/color v1.15.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
golang.org/x/sys v0.6.0 // indirect
)
+10
View File
@@ -0,0 +1,10 @@
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+72 -60
View File
@@ -1,78 +1,90 @@
package main package main
import ( import (
"bufio"
"fmt" "fmt"
"os"
"strings"
) )
type Todo struct { func PrintMenu() {
Title string fmt.Printf("\n\n### TODO APP ###\n")
Content string fmt.Printf("1: List Todo\n")
fmt.Printf("2: Add Todo\n")
fmt.Printf("3: Remove Todo (via index)\n")
fmt.Printf("4: Save to file\n")
fmt.Printf("\n\n0: Quit\n> ")
} }
type Todos struct { const (
Items []Todo QUIT = 0
} LIST = 1
ADD = 2
REMOVE = 3
SAVE = 4
)
func (todo *Todos) AddTodo(newTodo Todo) {
todo.Items = append(todo.Items, newTodo)
}
func (todo *Todos) RemoveTodo(index int) {
//remove todo via index
todo.Items = append(todo.Items[:index], todo.Items[index+1:]...)
}
func (todo *Todos) ListTodosFull() {
//List all the contents
if len(todo.Items) == 0 {
fmt.Printf("empty\n")
}
for k, v := range todo.Items {
fmt.Printf("%d:%s\n", k, v)
}
}
func ListTodosSmall() {
fmt.Println("ListTodosSmall func. not implemented")
//List all the contents
}
func main() { func main() {
fmt.Println("TODO APP") fmt.Print("\033[H\033[2J") //clear
PrintMenu()
list := Todos{} list := Todos{}
//todos := []Todo{} for {
//list := Todos{todos}
fmt.Println("Empty list: ")
list.ListTodosFull()
fmt.Println("Adding entries...") var input int
items := []Todo{ n, err := fmt.Scanln(&input)
{ if n < 1 || err != nil {
Title: "test", fmt.Print("[ERR] Invalid input\n")
Content: "Here is some content",
},
{
Title: "test1",
Content: "Here is some more content",
},
{
Title: "test2",
Content: "Here is even MORE content",
},
} }
//Add the items for testing switch input {
for item := range items { case QUIT:
list.AddTodo(items[item]) fmt.Print("Quitting, goodbye!\n")
os.Exit(0)
case LIST:
if err := list.ListTodo(); err != nil {
fmt.Print(err)
}
PrintMenu()
case ADD:
in := bufio.NewReader(os.Stdin)
fmt.Print("Add Title:\n> ")
title, _ := in.ReadString('\n')
fmt.Print("Add Content:\n> ")
content, _ := in.ReadString('\n')
list.AddTodo(Todo{Title: title, Content: content})
fmt.Printf("Added %s to the list!\n", title)
PrintMenu()
case REMOVE:
var index int
fmt.Printf("Which TODO to remove?\n> ")
if _, err := fmt.Scanf("%d", &index); err != nil {
fmt.Printf("Which TODO to remove?\n> ")
} }
fmt.Println("Listing...") if err := list.RemoveTodo(index); err != nil {
list.ListTodosFull() fmt.Print(err)
fmt.Println("Listing again...") }
list.ListTodosFull() PrintMenu()
case SAVE:
in := bufio.NewReader(os.Stdin)
fmt.Print("Save to file:\n> ")
filename, _ := in.ReadString('\n')
filename = strings.TrimSuffix(filename, "\n")
fmt.Println("Removing item2 via index 1") if err := list.SaveToFile(filename); err != nil {
list.RemoveTodo(1) fmt.Print(err)
fmt.Println("Listing again...") } else {
list.ListTodosFull() fmt.Printf("%s saved!\n", filename)
}
PrintMenu()
default:
PrintMenu()
}
}
} }
BIN
View File
Binary file not shown.
+98
View File
@@ -0,0 +1,98 @@
package main
import (
"errors"
"fmt"
"os"
"strconv"
"strings"
"github.com/fatih/color"
)
func check(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "[ERR] %s", err)
}
}
type Todo struct {
Title string
Content string
}
type Todos struct {
Items []Todo
}
func (todo *Todos) AddTodo(newTodo Todo) {
todo.Items = append(todo.Items, newTodo)
}
func (todo *Todos) RemoveTodo(index int) (err error) {
//remove todo via index
if len(todo.Items) == 0 {
return errors.New("[ERR] Todo list is empty!\n")
}
if index > len(todo.Items) {
return errors.New("[ERR] Index out of bounds\n")
}
todo.Items = append(todo.Items[:index], todo.Items[index+1:]...)
return nil
}
func (todo *Todos) ListTodo() (err error) {
// Create a custom print function for convenience
id := color.New(color.Bold, color.FgGreen).PrintfFunc()
title := color.New(color.Bold, color.FgBlue).PrintfFunc()
content := color.New(color.Bold, color.FgWhite).PrintfFunc()
if len(todo.Items) == 0 {
return errors.New("[ERR] Todo list is empty!\n")
}
for k, v := range todo.Items {
id("[%d]", k)
title("%s", v.Title)
content("%s\n", v.Content)
}
return nil
}
func (todo *Todos) SaveToFile(filename string) error {
var sb strings.Builder
var FILE *os.File
filename = filename + ".txt"
for k, v := range todo.Items {
fmt.Printf("#%d,%s,%s;\n", k, strings.ReplaceAll(v.Title, "\n", ""), strings.ReplaceAll(v.Content, "\n", ""))
sb.WriteString(strconv.Itoa(k))
sb.WriteString(",")
sb.WriteString(strings.ReplaceAll(v.Title, "\n", ""))
sb.WriteString(",")
sb.WriteString(strings.ReplaceAll(v.Content, "\n", ""))
sb.WriteString(";\n")
}
content := sb.String()
fmt.Println(content)
if _, err := os.Stat(filename); err != nil {
if FILE, err = os.Create(filename); err != nil {
return errors.New("[ERR] could not create file \n")
}
return errors.New("[ERR] file does not exist, creating one...\n")
}
FILE, _ = os.Create(filename) //errors already handled
if _, err := FILE.WriteString(content); err != nil {
return err
//return errors.New("[ERR] could not write to file\n")
}
sb.Reset() //reset the string builder
FILE.Close() //close the file
return nil
}