From 3d8aa853580663305d322a91a32789d8a5c75d98 Mon Sep 17 00:00:00 2001 From: zekroTJA Date: Thu, 16 Jul 2026 10:59:34 +0200 Subject: [PATCH] add go examples --- 05-typestate-go-structs/go.mod | 3 ++ 05-typestate-go-structs/main.go | 45 ++++++++++++++++ 06-typestate-go-interfaces/go.mod | 3 ++ 06-typestate-go-interfaces/main.go | 54 ++++++++++++++++++++ {05-type-mapping => 07-type-mapping}/main.ts | 0 go.work | 6 +++ 6 files changed, 111 insertions(+) create mode 100644 05-typestate-go-structs/go.mod create mode 100644 05-typestate-go-structs/main.go create mode 100644 06-typestate-go-interfaces/go.mod create mode 100644 06-typestate-go-interfaces/main.go rename {05-type-mapping => 07-type-mapping}/main.ts (100%) create mode 100644 go.work diff --git a/05-typestate-go-structs/go.mod b/05-typestate-go-structs/go.mod new file mode 100644 index 0000000..6f20c44 --- /dev/null +++ b/05-typestate-go-structs/go.mod @@ -0,0 +1,3 @@ +module typestate-structs + +go 1.26.5 diff --git a/05-typestate-go-structs/main.go b/05-typestate-go-structs/main.go new file mode 100644 index 0000000..6957835 --- /dev/null +++ b/05-typestate-go-structs/main.go @@ -0,0 +1,45 @@ +package main + +type LockedCredentialManager struct { + entries map[string]string +} + +type UnlockedCredentialManager struct { + entries map[string]string +} + +func NewCredentialManager() LockedCredentialManager { + return LockedCredentialManager{ + entries: make(map[string]string), + } +} + +func (m LockedCredentialManager) Unlock(masterSecret string) UnlockedCredentialManager { + return UnlockedCredentialManager{ + entries: m.entries, + } +} + +func (m UnlockedCredentialManager) Set(key string, secret string) { + panic("todo") +} + +func (m UnlockedCredentialManager) Get(key string) (string, bool) { + panic("todo") +} + +func (m UnlockedCredentialManager) Lock() LockedCredentialManager { + return LockedCredentialManager{ + entries: m.entries, + } +} + +func main() { + pw := NewCredentialManager() + + unlocked := pw.Unlock("pssst") + unlocked.Set("foo", "bar") + _, _ = unlocked.Get("foo") + + unlocked.Lock() +} diff --git a/06-typestate-go-interfaces/go.mod b/06-typestate-go-interfaces/go.mod new file mode 100644 index 0000000..803b7c7 --- /dev/null +++ b/06-typestate-go-interfaces/go.mod @@ -0,0 +1,3 @@ +module typestate-interfaces + +go 1.26.5 diff --git a/06-typestate-go-interfaces/main.go b/06-typestate-go-interfaces/main.go new file mode 100644 index 0000000..13b5719 --- /dev/null +++ b/06-typestate-go-interfaces/main.go @@ -0,0 +1,54 @@ +package main + +import "errors" + +type LockedCredentialManager interface { + Unlock(masterKey string) (UnlockedCredentialManager, error) +} + +type UnlockedCredentialManager interface { + Lock() (LockedCredentialManager, error) + Set(key string, secret string) error + Get(key string) (string, error) +} + +type credentialManager struct { + unlocked bool + entries map[string]string +} + +func NewCredentialManager() LockedCredentialManager { + return &credentialManager{ + entries: make(map[string]string), + } +} + +func (t *credentialManager) Unlock(masterKey string) (UnlockedCredentialManager, error) { + if t.unlocked { + return nil, errors.New("already unlocked") + } + t.unlocked = true + return t, nil +} + +func (t *credentialManager) Lock() (LockedCredentialManager, error) { + if !t.unlocked { + return nil, errors.New("already locked") + } + t.unlocked = false + return t, nil +} + +func (t *credentialManager) Set(key string, secret string) error { + if !t.unlocked { + return errors.New("locked") + } + panic("todo") +} + +func (t *credentialManager) Get(key string) (string, error) { + if !t.unlocked { + return "", errors.New("locked") + } + panic("todo") +} diff --git a/05-type-mapping/main.ts b/07-type-mapping/main.ts similarity index 100% rename from 05-type-mapping/main.ts rename to 07-type-mapping/main.ts diff --git a/go.work b/go.work new file mode 100644 index 0000000..9ac69b5 --- /dev/null +++ b/go.work @@ -0,0 +1,6 @@ +go 1.26.5 + +use ( + ./05-typestate-go-structs + ./06-typestate-go-interfaces +)