lntypes: Add Dual[A] primitive type

This commit introduces a new type Dual[A] to make it easier to
manage symmetric configurations or state for lightning channels.
This commit is contained in:
Keagan McClelland 2024-05-22 16:55:41 -07:00 committed by Oliver Gugger
parent d72a3aaf26
commit 8344699a0d
No known key found for this signature in database
GPG Key ID: 8E4256593F177720

View File

@ -50,3 +50,70 @@ func (p ChannelParty) IsLocal() bool {
func (p ChannelParty) IsRemote() bool {
return p == Remote
}
// Dual represents a structure when we are tracking the same parameter for both
// the Local and Remote parties.
type Dual[A any] struct {
// Local is the value tracked for the Local ChannelParty.
Local A
// Remote is the value tracked for the Remote ChannelParty.
Remote A
}
// GetForParty gives Dual an access method that takes a ChannelParty as an
// argument. It is included for ergonomics in cases where the ChannelParty is
// in a variable and which party determines how we want to access the Dual.
func (d *Dual[A]) GetForParty(p ChannelParty) A {
switch p {
case Local:
return d.Local
case Remote:
return d.Remote
default:
panic(fmt.Sprintf(
"switch default triggered in ForParty: %v", p,
))
}
}
// SetForParty sets the value in the Dual for the given ChannelParty. This
// returns a copy of the original value.
func (d *Dual[A]) SetForParty(p ChannelParty, value A) {
switch p {
case Local:
d.Local = value
case Remote:
d.Remote = value
default:
panic(fmt.Sprintf(
"switch default triggered in ForParty: %v", p,
))
}
}
// ModifyForParty applies the function argument to the given ChannelParty field
// and returns a new copy of the Dual.
func (d *Dual[A]) ModifyForParty(p ChannelParty, f func(A) A) A {
switch p {
case Local:
d.Local = f(d.Local)
return d.Local
case Remote:
d.Remote = f(d.Remote)
return d.Remote
default:
panic(fmt.Sprintf(
"switch default triggered in ForParty: %v", p,
))
}
}
// MapDual applies the function argument to both the Local and Remote fields of
// the Dual[A] and returns a Dual[B] with that function applied.
func MapDual[A, B any](d Dual[A], f func(A) B) Dual[B] {
return Dual[B]{
Local: f(d.Local),
Remote: f(d.Remote),
}
}