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)
 | |
| 	}
 | |
| }
 |