Skip to content

Commit

Permalink
lesson 4
Browse files Browse the repository at this point in the history
  • Loading branch information
bodrovis committed May 28, 2024
1 parent dbc9303 commit 2a3aa95
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 0 deletions.
57 changes: 57 additions & 0 deletions lesson_4/phonebook/book/book.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package book

import (
"fmt"
"time"
)

type PhoneBook map[string]PhoneNumber

type PhoneNumber struct {
Number string
LastUpdatedAt int64
}

func (book *PhoneBook) Add(name, phoneNum string) error {
if _, exists := (*book)[name]; exists {
return fmt.Errorf("name %s already exists", name)
}

(*book)[name] = PhoneNumber{
Number: phoneNum,
LastUpdatedAt: time.Now().Unix(),
}

return nil
}

func (book *PhoneBook) Get(name string) (PhoneNumber, error) {
if numberData, exists := (*book)[name]; exists {
return numberData, nil
}

return PhoneNumber{}, fmt.Errorf("no entry found for %s", name)
}

func (book *PhoneBook) Update(name, newPhoneNum string) error {
if _, exists := (*book)[name]; !exists {
return fmt.Errorf("name %s does not exist", name)
}

(*book)[name] = PhoneNumber{
Number: newPhoneNum,
LastUpdatedAt: time.Now().Unix(),
}

return nil
}

func (book *PhoneBook) Delete(name string) error {
if _, exists := (*book)[name]; !exists {
return fmt.Errorf("name %s does not exist", name)
}

delete(*book, name)

return nil
}
3 changes: 3 additions & 0 deletions lesson_4/phonebook/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module phonebook

go 1.22.2
30 changes: 30 additions & 0 deletions lesson_4/phonebook/logger/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package logger

import (
"fmt"
"log"
"os"
"strings"
)

var (
warnLogger = log.New(os.Stdout, "WARN: ", log.LstdFlags)
infoLogger = log.New(os.Stdout, "INFO: ", log.LstdFlags)
)

func Info(message string) {
infoLogger.Println(message)
}

func Warn(err error, messages ...string) {
if err == nil {
return
}

message := "An error occurred"
if len(messages) > 0 {
message = fmt.Sprintf("%s: %s", message, strings.Join(messages, " "))
}

warnLogger.Printf("%s: %v", message, err)
}
157 changes: 157 additions & 0 deletions lesson_4/phonebook/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package main

import (
"bufio"
"errors"
"fmt"
"os"
"strings"
"time"

"phonebook/book"
"phonebook/logger"
)

func main() {
phoneBook := make(book.PhoneBook)

scanner := bufio.NewScanner(os.Stdin)
fmt.Println("Welcome to the Phonebook")
fmt.Println("Available commands: add, get, delete, update, list, exit")

for {
fmt.Print("> ")
if !scanner.Scan() {
break
}
line := scanner.Text()
parts := strings.SplitN(line, " ", 2)
command := parts[0]
args := parts[1:]
// add alice=12345
switch command {
case "add":
handleCommand(doAdd, args, phoneBook)
case "get":
handleCommand(doGet, args, phoneBook)
case "list":
handleCommand(doList, args, phoneBook)
case "update":
handleCommand(doUpdate, args, phoneBook)
case "delete":
handleCommand(doDelete, args, phoneBook)
case "exit":
logger.Info("exiting phonebook, bye!")
return
default:
logger.Warn(errors.New("unsupported command. Try 'add', 'get', 'delete', 'update', 'list', or 'exit'"))
}
}
}

func handleCommand(cmd func([]string, book.PhoneBook) error, args []string, phoneBook book.PhoneBook) {
if err := cmd(args, phoneBook); err != nil {
logger.Warn(err, "command failed")
}
}

func doDelete(args []string, phoneBook book.PhoneBook) error {
if len(args) < 1 {
return errors.New("missing parameters for 'delete' command. Use: delete name")
}

name := args[0]

err := phoneBook.Delete(name)
if err != nil {
return err
}

logger.Info(fmt.Sprintf("Deleted entry for %s\n", name))

return nil
}

func doUpdate(args []string, phoneBook book.PhoneBook) error {
if len(args) < 1 {
return errors.New("missing parameters for 'update' command. Use: update name=new_number")
}

kv := strings.SplitN(args[0], "=", 2)
if len(kv) != 2 {
return errors.New("invalid format. Use: update name=number")
}

name, newNumber := kv[0], kv[1]

err := phoneBook.Update(name, newNumber)
if err != nil {
return err
}

logger.Info(fmt.Sprintf("Updated an entry: %s -> %s\n", name, newNumber))

return nil
}

func doList(_ []string, phoneBook book.PhoneBook) error {
if len(phoneBook) == 0 {
return errors.New("phonebook is empty")
} else {
results := ""

for name, number := range phoneBook {
results += fmt.Sprintf("%s -> %s\n", name, number.Number)
}

logger.Info(results)
}

return nil
}

func doGet(args []string, phoneBook book.PhoneBook) error {
if len(args) < 1 {
return errors.New("missing parameters for 'get' command. Use: get name")
}

name := args[0]

numberData, err := phoneBook.Get(name)
if err != nil {
return err
}

unixUpdatedAt := time.Unix(numberData.LastUpdatedAt, 0)

logger.Info(
fmt.Sprintf("Number for %s is %s (last updated at %s)\n",
name,
numberData.Number,
unixUpdatedAt.Format("2006-01-02 15:04:05"),
),
)

return nil
}

func doAdd(args []string, phoneBook book.PhoneBook) error {
if len(args) < 1 {
return errors.New("missing parameters for 'add' command. Use: add name=number")
}

kv := strings.SplitN(args[0], "=", 2)
if len(kv) != 2 {
return errors.New("invalid format. Use: add name=number")
}

name, number := kv[0], kv[1]
err := phoneBook.Add(name, number)
if err != nil {
return err
}

logger.Info(fmt.Sprintf("Added an entry: %s -> %s\n", name, number))

return nil
}

0 comments on commit 2a3aa95

Please sign in to comment.