huh/eval.go
Maas Lalani 1f1f7a2a83
Dynamic Inputs (#233)
* feat: dynamic

Adds `Func`-able properties to all fields to allow dynamic updates
based on updates in other parts of the group.

Note that bindings must be specified. Bindings allow the Function to
know when it should update as the functoin re-evaluates only when the
value of the binding changes.

* chore(deps): bump deps

* fix: PR Review

* fix: update value when options change with OptionsFunc

* fix: rebase

* fix: update value should modify select
2024-07-09 18:01:26 -04:00

85 lines
1.4 KiB
Go

package huh
import (
"time"
"github.com/mitchellh/hashstructure/v2"
)
// Eval is an evaluatable value, it stores a cached value and a function to
// recompute it. It's bindings are what we check to see if we need to recompute
// the value.
//
// By default it is also cached.
type Eval[T any] struct {
val T
fn func() T
bindings any
bindingsHash uint64
cache map[uint64]T
loading bool
loadingStart time.Time
}
const spinnerShowThreshold = 25 * time.Millisecond
func hash(val any) uint64 {
hash, _ := hashstructure.Hash(val, hashstructure.FormatV2, nil)
return hash
}
func (e *Eval[T]) shouldUpdate() (bool, uint64) {
if e.fn == nil {
return false, 0
}
newHash := hash(e.bindings)
return e.bindingsHash != newHash, newHash
}
func (e *Eval[T]) loadFromCache() bool {
val, ok := e.cache[e.bindingsHash]
if ok {
e.loading = false
e.val = val
}
return ok
}
func (e *Eval[T]) update(val T) {
e.val = val
e.cache[e.bindingsHash] = val
e.loading = false
}
type updateTitleMsg struct {
id int
hash uint64
title string
}
type updateDescriptionMsg struct {
id int
hash uint64
description string
}
type updatePlaceholderMsg struct {
id int
hash uint64
placeholder string
}
type updateSuggestionsMsg struct {
id int
hash uint64
suggestions []string
}
type updateOptionsMsg[T comparable] struct {
id int
hash uint64
options []Option[T]
}