62 lines
1.6 KiB
Go
62 lines
1.6 KiB
Go
package niri
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
)
|
|
|
|
type PositionChange struct {
|
|
SetFixed Option[int] `json:"SetFixed,omitempty"`
|
|
AdjustFixed Option[int] `json:"AdjustFixed,omitempty"`
|
|
}
|
|
|
|
func (m PositionChange) String() string {
|
|
data, _ := json.MarshalIndent(m, "", "\t")
|
|
return string(data)
|
|
}
|
|
|
|
func PositionSetFixed(position int) PositionChange {
|
|
return PositionChange{SetFixed: &position}
|
|
}
|
|
|
|
func PositionAdjustFixed(position int) PositionChange {
|
|
return PositionChange{AdjustFixed: &position}
|
|
}
|
|
|
|
const positionPatternString = `^(\+|-)?(\d+?)$`
|
|
const positionPatternGroupAdjust = 1
|
|
const positionPatternGroupIntValue = 2
|
|
|
|
var positionPattern = regexp.MustCompile(positionPatternString)
|
|
|
|
func ParsePosition(str string) (PositionChange, error) {
|
|
matches := positionPattern.FindStringSubmatch(str)
|
|
if matches == nil {
|
|
return PositionChange{}, fmt.Errorf("invalid position spec '%s'. Expected pattern: %s", str, positionPatternString)
|
|
}
|
|
|
|
adjust := matches[positionPatternGroupAdjust] != ""
|
|
negative := matches[positionPatternGroupAdjust] == "-"
|
|
|
|
factor := 1
|
|
if negative {
|
|
factor = -1
|
|
}
|
|
|
|
intValue, err := strconv.ParseInt(matches[positionPatternGroupIntValue], 10, 64)
|
|
if err != nil {
|
|
return PositionChange{}, fmt.Errorf("invalid position spec '%s'. Expected pattern: %s", str, positionPatternString)
|
|
}
|
|
|
|
switch true {
|
|
case adjust:
|
|
return PositionAdjustFixed(int(intValue) * factor), nil
|
|
case !adjust:
|
|
return PositionSetFixed(int(intValue) * factor), nil
|
|
default:
|
|
return PositionChange{}, fmt.Errorf("invalid position spec '%s'. Expected pattern: %s", str, positionPatternString)
|
|
}
|
|
}
|