go-i3/command.go
2023-10-22 16:19:10 +02:00

65 lines
1.7 KiB
Go

package i3
import (
"encoding/json"
"fmt"
)
// CommandResult always contains Success, and command-specific fields where
// appropriate.
type CommandResult struct {
// Success indicates whether the command was run without any errors.
Success bool `json:"success"`
// Error is a human-readable error message, non-empty for unsuccessful
// commands.
Error string `json:"error"`
}
// IsUnsuccessful is a convenience function which can be used to check if an
// error is a CommandUnsuccessfulError.
func IsUnsuccessful(err error) bool {
_, ok := err.(*CommandUnsuccessfulError)
return ok
}
// CommandUnsuccessfulError is returned by RunCommand for unsuccessful
// commands. This type is exported so that you can ignore this error if you
// expect your command(s) to fail.
type CommandUnsuccessfulError struct {
command string
cr CommandResult
}
// Error implements error.
func (e *CommandUnsuccessfulError) Error() string {
return fmt.Sprintf("command %q unsuccessful: %v", e.command, e.cr.Error)
}
// RunCommand makes i3 run the specified command.
//
// Error is non-nil if any CommandResult.Success is not true. See IsUnsuccessful
// if you send commands which are expected to fail.
//
// RunCommand is supported in i3 ≥ v4.0 (2011-07-31).
func RunCommand(command string) ([]CommandResult, error) {
reply, err := roundTrip(messageTypeRunCommand, []byte(command))
if err != nil {
return []CommandResult{}, err
}
var crs []CommandResult
err = json.Unmarshal(reply.Payload, &crs)
if err == nil {
for _, cr := range crs {
if !cr.Success {
return crs, &CommandUnsuccessfulError{
command: command,
cr: cr,
}
}
}
}
return crs, err
}