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() }