typetui 0.2.0

A terminal-based typing test.
Documentation
package main

import (
    "fmt"
    "time"
)

type User struct {
    ID        int       `json:"id" db:"user_id"`
    Name      string    `json:"name" validate:"required"`
    Email     string    `json:"email" validate:"email"`
    CreatedAt time.Time `json:"created_at"`
}

func NewUser(name, email string) *User {
    return &User{
        Name:      name,
        Email:     email,
        CreatedAt: time.Now(),
    }
}

func (u *User) UpdateEmail(email string) {
    u.Email = email
}

func (u User) DisplayName() string {
    return fmt.Sprintf("%s <%s>", u.Name, u.Email)
}

type Namer interface {
    DisplayName() string
}

type Identifier interface {
    GetID() int
}

type Entity struct {
    ID int
}

func (e Entity) GetID() int {
    return e.ID
}

type Admin struct {
    Entity
    Name  string
    Perms []string
}

type Resource interface {
    Namer
    Identifier
}

type Logger interface {
    Log(msg string)
}

type Cache interface {
    Get(key string) (string, bool)
    Set(key, value string)
}

type Service struct {
    name  string
    cache map[string]string
}

func (s *Service) DisplayName() string {
    return s.name
}

func (s *Service) GetID() int {
    return 1
}

func (s *Service) Log(msg string) {
    fmt.Printf("[%s] %s\n", s.name, msg)
}

func (s *Service) Get(key string) (string, bool) {
    val, ok := s.cache[key]
    return val, ok
}

func (s *Service) Set(key, value string) {
    s.cache[key] = value
}

func PrintAnything(v interface{}) {
    switch val := v.(type) {
    case string:
        fmt.Println("String:", val)
    case int:
        fmt.Println("Int:", val)
    case Namer:
        fmt.Println("Namer:", val.DisplayName())
    default:
        fmt.Printf("Unknown: %T\n", val)
    }
}

type Stringer interface {
    String() string
}

func ToString(v interface{}) string {
    if s, ok := v.(Stringer); ok {
        return s.String()
    }
    return fmt.Sprintf("%v", v)
}

func main() {
    user := User{
        ID:    1,
        Name:  "Alice",
        Email: "alice@example.com",
    }

    user2 := NewUser("Bob", "bob@example.com")
    user.UpdateEmail("alice.new@example.com")
    var namer Namer = &user
    fmt.Println(namer.DisplayName())

    admin := Admin{
        Entity: Entity{ID: 100},
        Name:   "Super Admin",
        Perms:  []string{"read", "write", "delete"},
    }
    fmt.Println("Admin ID:", admin.GetID())
    PrintAnything(user)
    PrintAnything(42)
}