Compare commits

...

7 Commits

9 changed files with 636 additions and 7 deletions

View File

@ -23,6 +23,7 @@ Available Commands:
headamp Commands to control headamp gain and phantom power headamp Commands to control headamp gain and phantom power
help Help about any command help Help about any command
main Commands to control the main output main Commands to control the main output
raw Send a raw OSC message to the mixer
strip Commands to control individual strips strip Commands to control individual strips
Flags: Flags:

View File

@ -568,6 +568,47 @@ var busCompOnCmd = &cobra.Command{
}, },
} }
// busCompModeCmd represents the bus Compressor mode command.
var busCompModeCmd = &cobra.Command{
Short: "Get or set the bus Compressor mode",
Long: `Get or set the Compressor mode of a specific bus.`,
Use: "mode [bus number] [mode]",
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 1 {
return fmt.Errorf("Please provide bus number")
}
busIndex := mustConvToInt(args[0])
if len(args) == 1 {
mode, err := client.Bus.Comp.Mode(busIndex)
if err != nil {
return fmt.Errorf("Error getting bus Compressor mode: %w", err)
}
cmd.Printf("Bus %d Compressor mode: %s\n", busIndex, mode)
return nil
}
mode := args[1]
if !contains([]string{"comp", "exp"}, mode) {
return fmt.Errorf("Invalid mode value. Valid values are: comp, exp")
}
err := client.Bus.Comp.SetMode(busIndex, mode)
if err != nil {
return fmt.Errorf("Error setting bus Compressor mode: %w", err)
}
cmd.Printf("Bus %d Compressor mode set to %s\n", busIndex, mode)
return nil
},
}
// busCompThresholdCmd represents the bus Compressor threshold command. // busCompThresholdCmd represents the bus Compressor threshold command.
var busCompThresholdCmd = &cobra.Command{ var busCompThresholdCmd = &cobra.Command{
Short: "Get or set the bus Compressor threshold", Short: "Get or set the bus Compressor threshold",
@ -883,6 +924,7 @@ func init() {
busCmd.AddCommand(busCompCmd) busCmd.AddCommand(busCompCmd)
busCompCmd.AddCommand(busCompOnCmd) busCompCmd.AddCommand(busCompOnCmd)
busCompCmd.AddCommand(busCompModeCmd)
busCompCmd.AddCommand(busCompThresholdCmd) busCompCmd.AddCommand(busCompThresholdCmd)
busCompCmd.AddCommand(busCompRatioCmd) busCompCmd.AddCommand(busCompRatioCmd)
busCompCmd.AddCommand(busCompMixCmd) busCompCmd.AddCommand(busCompMixCmd)

58
cmd/raw.go Normal file
View File

@ -0,0 +1,58 @@
package cmd
import (
"fmt"
"time"
"github.com/spf13/cobra"
)
// rawCmd represents the raw command
var rawCmd = &cobra.Command{
Short: "Send a raw OSC message to the mixer",
Long: `Send a raw OSC message to the mixer.
You need to provide the OSC address and any parameters as arguments.
Optionally provide a timeout duration to wait for a response from the mixer. Default is 200ms.`,
Use: "raw",
Example: ` xair-cli raw /xinfo
xair-cli raw /ch/01/mix/fader 0.75
xair-cli raw --timeout 500ms /bus/2/mix/on 1`,
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("no client found in context")
}
command := args[0]
params := make([]any, len(args[1:]))
for i, arg := range args[1:] {
params[i] = arg
}
if err := client.SendMessage(command, params...); err != nil {
return fmt.Errorf("error sending message: %v", err)
}
timeout, err := cmd.Flags().GetDuration("timeout")
if err != nil {
return fmt.Errorf("error getting timeout flag: %v", err)
}
msg, err := client.ReceiveMessage(timeout)
if err != nil {
return fmt.Errorf("error receiving message: %v", err)
}
if msg != nil {
fmt.Printf("Received response: %v\n", msg)
}
return nil
},
}
func init() {
rootCmd.AddCommand(rawCmd)
rawCmd.Flags().DurationP("timeout", "t", 200*time.Millisecond, "Timeout duration for receiving a response")
}

View File

@ -404,6 +404,249 @@ If "false" or "0" is provided, the Gate is turned off.`,
}, },
} }
// stripGateModeCmd represents the strip Gate Mode command.
var stripGateModeCmd = &cobra.Command{
Short: "Get or set the Gate mode for a strip",
Long: "Get or set the Gate mode for a specific strip.",
Use: "mode [strip number] [mode]",
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 1 {
return fmt.Errorf("Please provide a strip number")
}
stripIndex := mustConvToInt(args[0])
if len(args) == 1 {
currentMode, err := client.Strip.Gate.Mode(stripIndex)
if err != nil {
return fmt.Errorf("Error getting strip Gate mode: %w", err)
}
cmd.Printf("Strip %d Gate mode: %s\n", stripIndex, currentMode)
return nil
}
if len(args) < 2 {
return fmt.Errorf("Please provide a mode")
}
mode := args[1]
possibleModes := []string{"exp2", "exp3", "exp4", "gate", "duck"}
if !contains(possibleModes, mode) {
return fmt.Errorf("Invalid mode value. Valid values are: %v", possibleModes)
}
err := client.Strip.Gate.SetMode(stripIndex, mode)
if err != nil {
return fmt.Errorf("Error setting strip Gate mode: %w", err)
}
cmd.Printf("Strip %d Gate mode set to %s\n", stripIndex, mode)
return nil
},
}
// stripGateThresholdCmd represents the strip Gate Threshold command.
var stripGateThresholdCmd = &cobra.Command{
Short: "Get or set the Gate threshold for a strip",
Long: "Get or set the Gate threshold for a specific strip.",
Use: "threshold [strip number] [threshold in dB]",
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 1 {
return fmt.Errorf("Please provide a strip number")
}
stripIndex := mustConvToInt(args[0])
if len(args) == 1 {
currentThreshold, err := client.Strip.Gate.Threshold(stripIndex)
if err != nil {
return fmt.Errorf("Error getting strip Gate threshold: %w", err)
}
cmd.Printf("Strip %d Gate threshold: %.2f dB\n", stripIndex, currentThreshold)
return nil
}
if len(args) < 2 {
return fmt.Errorf("Please provide a threshold in dB")
}
threshold := mustConvToFloat64(args[1])
err := client.Strip.Gate.SetThreshold(stripIndex, threshold)
if err != nil {
return fmt.Errorf("Error setting strip Gate threshold: %w", err)
}
cmd.Printf("Strip %d Gate threshold set to %.2f dB\n", stripIndex, threshold)
return nil
},
}
// stripGateRangeCmd represents the strip Gate Range command.
var stripGateRangeCmd = &cobra.Command{
Short: "Get or set the Gate range for a strip",
Long: "Get or set the Gate range for a specific strip.",
Use: "range [strip number] [range in dB]",
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 1 {
return fmt.Errorf("Please provide a strip number")
}
stripIndex := mustConvToInt(args[0])
if len(args) == 1 {
currentRange, err := client.Strip.Gate.Range(stripIndex)
if err != nil {
return fmt.Errorf("Error getting strip Gate range: %w", err)
}
cmd.Printf("Strip %d Gate range: %.2f dB\n", stripIndex, currentRange)
return nil
}
if len(args) < 2 {
return fmt.Errorf("Please provide a range in dB")
}
rangeDb := mustConvToFloat64(args[1])
err := client.Strip.Gate.SetRange(stripIndex, rangeDb)
if err != nil {
return fmt.Errorf("Error setting strip Gate range: %w", err)
}
cmd.Printf("Strip %d Gate range set to %.2f dB\n", stripIndex, rangeDb)
return nil
},
}
// stripGateAttackCmd represents the strip Gate Attack command.
var stripGateAttackCmd = &cobra.Command{
Short: "Get or set the Gate attack time for a strip",
Long: "Get or set the Gate attack time for a specific strip.",
Use: "attack [strip number] [attack time in ms]",
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 1 {
return fmt.Errorf("Please provide a strip number")
}
stripIndex := mustConvToInt(args[0])
if len(args) == 1 {
currentAttack, err := client.Strip.Gate.Attack(stripIndex)
if err != nil {
return fmt.Errorf("Error getting strip Gate attack time: %w", err)
}
cmd.Printf("Strip %d Gate attack time: %.2f ms\n", stripIndex, currentAttack)
return nil
}
if len(args) < 2 {
return fmt.Errorf("Please provide an attack time in ms")
}
attack := mustConvToFloat64(args[1])
err := client.Strip.Gate.SetAttack(stripIndex, attack)
if err != nil {
return fmt.Errorf("Error setting strip Gate attack time: %w", err)
}
cmd.Printf("Strip %d Gate attack time set to %.2f ms\n", stripIndex, attack)
return nil
},
}
// stripGateHoldCmd represents the strip Gate Hold command.
var stripGateHoldCmd = &cobra.Command{
Short: "Get or set the Gate hold time for a strip",
Long: "Get or set the Gate hold time for a specific strip.",
Use: "hold [strip number] [hold time in ms]",
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 1 {
return fmt.Errorf("Please provide a strip number")
}
stripIndex := mustConvToInt(args[0])
if len(args) == 1 {
currentHold, err := client.Strip.Gate.Hold(stripIndex)
if err != nil {
return fmt.Errorf("Error getting strip Gate hold time: %w", err)
}
cmd.Printf("Strip %d Gate hold time: %.2f ms\n", stripIndex, currentHold)
return nil
}
if len(args) < 2 {
return fmt.Errorf("Please provide a hold time in ms")
}
hold := mustConvToFloat64(args[1])
err := client.Strip.Gate.SetHold(stripIndex, hold)
if err != nil {
return fmt.Errorf("Error setting strip Gate hold time: %w", err)
}
cmd.Printf("Strip %d Gate hold time set to %.2f ms\n", stripIndex, hold)
return nil
},
}
// stripGateReleaseCmd represents the strip Gate Release command.
var stripGateReleaseCmd = &cobra.Command{
Short: "Get or set the Gate release time for a strip",
Long: "Get or set the Gate release time for a specific strip.",
Use: "release [strip number] [release time in ms]",
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 1 {
return fmt.Errorf("Please provide a strip number")
}
stripIndex := mustConvToInt(args[0])
if len(args) == 1 {
currentRelease, err := client.Strip.Gate.Release(stripIndex)
if err != nil {
return fmt.Errorf("Error getting strip Gate release time: %w", err)
}
cmd.Printf("Strip %d Gate release time: %.2f ms\n", stripIndex, currentRelease)
return nil
}
if len(args) < 2 {
return fmt.Errorf("Please provide a release time in ms")
}
release := mustConvToFloat64(args[1])
err := client.Strip.Gate.SetRelease(stripIndex, release)
if err != nil {
return fmt.Errorf("Error setting strip Gate release time: %w", err)
}
cmd.Printf("Strip %d Gate release time set to %.2f ms\n", stripIndex, release)
return nil
},
}
// stripEqCmd represents the strip EQ command. // stripEqCmd represents the strip EQ command.
var stripEqCmd = &cobra.Command{ var stripEqCmd = &cobra.Command{
Short: "Commands to control the EQ of individual strips.", Short: "Commands to control the EQ of individual strips.",
@ -727,6 +970,51 @@ If "false" or "0" is provided, the Compressor is turned off.`,
}, },
} }
// stripCompModeCmd represents the strip Compressor Mode command.
var stripCompModeCmd = &cobra.Command{
Short: "Get or set the Compressor mode for a strip",
Long: "Get or set the Compressor mode for a specific strip.",
Use: "mode [strip number] [mode]",
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 1 {
return fmt.Errorf("Please provide a strip number")
}
stripIndex := mustConvToInt(args[0])
if len(args) == 1 {
currentMode, err := client.Strip.Comp.Mode(stripIndex)
if err != nil {
return fmt.Errorf("Error getting strip Compressor mode: %w", err)
}
cmd.Printf("Strip %d Compressor mode: %s\n", stripIndex, currentMode)
return nil
}
if len(args) < 2 {
return fmt.Errorf("Please provide a mode")
}
mode := args[1]
if !contains([]string{"comp", "exp"}, mode) {
return fmt.Errorf("Invalid mode value. Valid values are: comp, exp")
}
err := client.Strip.Comp.SetMode(stripIndex, mode)
if err != nil {
return fmt.Errorf("Error setting strip Compressor mode: %w", err)
}
cmd.Printf("Strip %d Compressor mode set to %s\n", stripIndex, mode)
return nil
},
}
// stripCompThresholdCmd represents the strip Compressor Threshold command. // stripCompThresholdCmd represents the strip Compressor Threshold command.
var stripCompThresholdCmd = &cobra.Command{ var stripCompThresholdCmd = &cobra.Command{
Short: "Get or set the Compressor threshold for a strip", Short: "Get or set the Compressor threshold for a strip",
@ -1039,6 +1327,12 @@ func init() {
stripCmd.AddCommand(stripGateCmd) stripCmd.AddCommand(stripGateCmd)
stripGateCmd.AddCommand(stripGateOnCmd) stripGateCmd.AddCommand(stripGateOnCmd)
stripGateCmd.AddCommand(stripGateModeCmd)
stripGateCmd.AddCommand(stripGateThresholdCmd)
stripGateCmd.AddCommand(stripGateRangeCmd)
stripGateCmd.AddCommand(stripGateAttackCmd)
stripGateCmd.AddCommand(stripGateHoldCmd)
stripGateCmd.AddCommand(stripGateReleaseCmd)
stripCmd.AddCommand(stripEqCmd) stripCmd.AddCommand(stripEqCmd)
stripEqCmd.AddCommand(stripEqOnCmd) stripEqCmd.AddCommand(stripEqOnCmd)
@ -1049,6 +1343,7 @@ func init() {
stripCmd.AddCommand(stripCompCmd) stripCmd.AddCommand(stripCompCmd)
stripCompCmd.AddCommand(stripCompOnCmd) stripCompCmd.AddCommand(stripCompOnCmd)
stripCompCmd.AddCommand(stripCompModeCmd)
stripCompCmd.AddCommand(stripCompThresholdCmd) stripCompCmd.AddCommand(stripCompThresholdCmd)
stripCompCmd.AddCommand(stripCompRatioCmd) stripCompCmd.AddCommand(stripCompRatioCmd)
stripCompCmd.AddCommand(stripCompMixCmd) stripCompCmd.AddCommand(stripCompMixCmd)

View File

@ -4,6 +4,7 @@ var xairAddressMap = map[string]string{
"strip": "/ch/%02d", "strip": "/ch/%02d",
"bus": "/bus/%01d", "bus": "/bus/%01d",
"headamp": "/headamp/%02d", "headamp": "/headamp/%02d",
"snapshot": "/-snap",
} }
var x32AddressMap = map[string]string{ var x32AddressMap = map[string]string{

View File

@ -3,6 +3,7 @@ package xair
import ( import (
"fmt" "fmt"
"net" "net"
"time"
"github.com/charmbracelet/log" "github.com/charmbracelet/log"
@ -19,6 +20,7 @@ type Client struct {
Strip *Strip Strip *Strip
Bus *Bus Bus *Bus
HeadAmp *HeadAmp HeadAmp *HeadAmp
Snapshot *Snapshot
} }
// NewClient creates a new XAirClient instance // NewClient creates a new XAirClient instance
@ -85,6 +87,20 @@ func (c *Client) SendMessage(address string, args ...any) error {
return c.engine.sendToAddress(c.mixerAddr, address, args...) return c.engine.sendToAddress(c.mixerAddr, address, args...)
} }
// ReceiveMessage receives an OSC message from the mixer
func (c *Client) ReceiveMessage(timeout time.Duration) (*osc.Message, error) {
t := time.Tick(timeout)
select {
case <-t:
return nil, nil
case val := <-c.respChan:
if val == nil {
return nil, fmt.Errorf("no message received")
}
return val, nil
}
}
// RequestInfo requests mixer information // RequestInfo requests mixer information
func (c *Client) RequestInfo() (error, InfoResponse) { func (c *Client) RequestInfo() (error, InfoResponse) {
err := c.SendMessage("/xinfo") err := c.SendMessage("/xinfo")

View File

@ -49,6 +49,31 @@ func (c *Comp) SetOn(index int, on bool) error {
return c.client.SendMessage(address, value) return c.client.SendMessage(address, value)
} }
// Mode retrieves the current mode of the Compressor for a specific strip or bus (1-based indexing).
func (c *Comp) Mode(index int) (string, error) {
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/mode"
err := c.client.SendMessage(address)
if err != nil {
return "", err
}
possibleModes := []string{"comp", "exp"}
resp := <-c.client.respChan
val, ok := resp.Arguments[0].(int32)
if !ok {
return "", fmt.Errorf("unexpected argument type for Compressor mode value")
}
return possibleModes[val], nil
}
// SetMode sets the mode of the Compressor for a specific strip or bus (1-based indexing).
func (c *Comp) SetMode(index int, mode string) error {
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/mode"
possibleModes := []string{"comp", "exp"}
return c.client.SendMessage(address, int32(indexOf(possibleModes, mode)))
}
// Threshold retrieves the threshold value of the Compressor for a specific strip or bus (1-based indexing). // Threshold retrieves the threshold value of the Compressor for a specific strip or bus (1-based indexing).
func (c *Comp) Threshold(index int) (float64, error) { func (c *Comp) Threshold(index int) (float64, error) {
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/thr" address := fmt.Sprintf(c.baseAddress, index) + "/dyn/thr"

View File

@ -36,3 +36,139 @@ func (g *Gate) SetOn(index int, on bool) error {
} }
return g.client.SendMessage(address, value) return g.client.SendMessage(address, value)
} }
// Mode retrieves the current mode of the Gate for a specific strip (1-based indexing).
func (g *Gate) Mode(index int) (string, error) {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/mode"
err := g.client.SendMessage(address)
if err != nil {
return "", err
}
possibleModes := []string{"exp2", "exp3", "exp4", "gate", "duck"}
resp := <-g.client.respChan
val, ok := resp.Arguments[0].(int32)
if !ok {
return "", fmt.Errorf("unexpected argument type for Gate mode value")
}
return possibleModes[val], nil
}
// SetMode sets the mode of the Gate for a specific strip (1-based indexing).
func (g *Gate) SetMode(index int, mode string) error {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/mode"
possibleModes := []string{"exp2", "exp3", "exp4", "gate", "duck"}
return g.client.SendMessage(address, int32(indexOf(possibleModes, mode)))
}
// Threshold retrieves the threshold value of the Gate for a specific strip (1-based indexing).
func (g *Gate) Threshold(index int) (float64, error) {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/thr"
err := g.client.SendMessage(address)
if err != nil {
return 0, err
}
resp := <-g.client.respChan
val, ok := resp.Arguments[0].(float32)
if !ok {
return 0, fmt.Errorf("unexpected argument type for Gate threshold value")
}
return linGet(-80, 0, float64(val)), nil
}
// SetThreshold sets the threshold value of the Gate for a specific strip (1-based indexing).
func (g *Gate) SetThreshold(index int, threshold float64) error {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/thr"
return g.client.SendMessage(address, float32(linSet(-80, 0, threshold)))
}
// Range retrieves the range value of the Gate for a specific strip (1-based indexing).
func (g *Gate) Range(index int) (float64, error) {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/range"
err := g.client.SendMessage(address)
if err != nil {
return 0, err
}
resp := <-g.client.respChan
val, ok := resp.Arguments[0].(float32)
if !ok {
return 0, fmt.Errorf("unexpected argument type for Gate range value")
}
return linGet(3, 60, float64(val)), nil
}
// SetRange sets the range value of the Gate for a specific strip (1-based indexing).
func (g *Gate) SetRange(index int, rangeVal float64) error {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/range"
return g.client.SendMessage(address, float32(linSet(3, 60, rangeVal)))
}
// Attack retrieves the attack time of the Gate for a specific strip (1-based indexing).
func (g *Gate) Attack(index int) (float64, error) {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/attack"
err := g.client.SendMessage(address)
if err != nil {
return 0, err
}
resp := <-g.client.respChan
val, ok := resp.Arguments[0].(float32)
if !ok {
return 0, fmt.Errorf("unexpected argument type for Gate attack value")
}
return linGet(0, 120, float64(val)), nil
}
// SetAttack sets the attack time of the Gate for a specific strip (1-based indexing).
func (g *Gate) SetAttack(index int, attack float64) error {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/attack"
return g.client.SendMessage(address, float32(linSet(0, 120, attack)))
}
// Hold retrieves the hold time of the Gate for a specific strip (1-based indexing).
func (g *Gate) Hold(index int) (float64, error) {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/hold"
err := g.client.SendMessage(address)
if err != nil {
return 0, err
}
resp := <-g.client.respChan
val, ok := resp.Arguments[0].(float32)
if !ok {
return 0, fmt.Errorf("unexpected argument type for Gate hold value")
}
return logGet(0.02, 2000, float64(val)), nil
}
// SetHold sets the hold time of the Gate for a specific strip (1-based indexing).
func (g *Gate) SetHold(index int, hold float64) error {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/hold"
return g.client.SendMessage(address, float32(logSet(0.02, 2000, hold)))
}
// Release retrieves the release time of the Gate for a specific strip (1-based indexing).
func (g *Gate) Release(index int) (float64, error) {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/release"
err := g.client.SendMessage(address)
if err != nil {
return 0, err
}
resp := <-g.client.respChan
val, ok := resp.Arguments[0].(float32)
if !ok {
return 0, fmt.Errorf("unexpected argument type for Gate release value")
}
return logGet(5, 4000, float64(val)), nil
}
// SetRelease sets the release time of the Gate for a specific strip (1-based indexing).
func (g *Gate) SetRelease(index int, release float64) error {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/release"
return g.client.SendMessage(address, float32(logSet(5, 4000, release)))
}

55
internal/xair/snapshot.go Normal file
View File

@ -0,0 +1,55 @@
package xair
import "fmt"
type Snapshot struct {
baseAddress string
client *Client
}
func NewSnapshot(c *Client) *Snapshot {
return &Snapshot{
baseAddress: c.addressMap["snapshot"],
client: c,
}
}
// Name gets the name of the snapshot at the given index.
func (s *Snapshot) Name(index int) (string, error) {
address := s.baseAddress + fmt.Sprintf("/name/%d", index)
err := s.client.SendMessage(address)
if err != nil {
return "", err
}
resp := <-s.client.respChan
name, ok := resp.Arguments[0].(string)
if !ok {
return "", fmt.Errorf("unexpected argument type for snapshot name")
}
return name, nil
}
// SetName sets the name of the snapshot at the given index.
func (s *Snapshot) SetName(index int, name string) error {
address := s.baseAddress + fmt.Sprintf("/name/%d", index)
return s.client.SendMessage(address, name)
}
// Load loads the snapshot at the given index.
func (s *Snapshot) Load(index int) error {
address := s.baseAddress + fmt.Sprintf("/load/%d", index)
return s.client.SendMessage(address)
}
// Save saves the current state to the snapshot at the given index.
func (s *Snapshot) Save(index int) error {
address := s.baseAddress + fmt.Sprintf("/save/%d", index)
return s.client.SendMessage(address)
}
// Delete deletes the snapshot at the given index.
func (s *Snapshot) Delete(index int) error {
address := s.baseAddress + fmt.Sprintf("/delete/%d", index)
return s.client.SendMessage(address)
}