@@ -46,6 +46,23 @@ var ErrInterrupted = errors.New("program was interrupted")
4646// function and, henceforth, the UI.
4747type Msg interface {}
4848
49+ // Model contains the program's state as well as its core functions.
50+ type Model [T any ] interface {
51+ // Init is the first function that will be called. It returns an optional
52+ // initial command. To not perform an initial command return nil.
53+ Init () (T , Cmd )
54+
55+ // Update is called when a message is received. Use it to inspect messages
56+ // and, in response, update the model and/or send a command.
57+ Update (Msg ) (T , Cmd )
58+
59+ // View renders the program's UI, which is just a [fmt.Stringer]. The view
60+ // is rendered after every Update.
61+ // The main model can return a [Frame] to set the cursor position and
62+ // style.
63+ View () fmt.Stringer
64+ }
65+
4966// Cmd is an IO operation that returns a message when it's complete. If it's
5067// nil it's considered a no-op. Use it for things like HTTP requests, timers,
5168// saving and loading from disk, and so on.
@@ -142,7 +159,7 @@ type Program[T any] struct {
142159 // To have more control over the cursor position and style, you can use
143160 // [Frame.Cursor] and [NewCursor] to position the cursor and define its
144161 // style.
145- View func (T ) Frame
162+ View func (T ) fmt. Stringer
146163
147164 // Model contains the last state of the program. If the program hasn't
148165 // started yet, it will be nil. After the program finish executing, it will
@@ -275,6 +292,15 @@ func Interrupt() Msg {
275292 return InterruptMsg {}
276293}
277294
295+ // NewProgram creates a new Program.
296+ func NewProgram [T any ](model Model [T ]) * Program [T ] {
297+ p := new (Program [T ])
298+ p .Init = model .Init
299+ p .Update = func (t T , msg Msg ) (T , Cmd ) { return any (t ).(Model [T ]).Update (msg ) }
300+ p .View = func (t T ) fmt.Stringer { return any (t ).(Model [T ]).View () }
301+ return p
302+ }
303+
278304func (p * Program [T ]) init () {
279305 if atomic .LoadInt32 (& p .initialized ) == 1 {
280306 return
0 commit comments