Files
niri/model_size_change.go
2025-07-25 13:41:23 +02:00

84 lines
2.3 KiB
Go

package niri
import (
"encoding/json"
"fmt"
"regexp"
"strconv"
)
type SizeChange struct {
SetFixed *int `json:"SetFixed,omitempty"`
SetProportion *float64 `json:"SetProportion,omitempty"`
AdjustFixed *int `json:"AdjustFixed,omitempty"`
AdjustProportion *float64 `json:"AdjustProportion,omitempty"`
}
func (m SizeChange) String() string {
data, _ := json.MarshalIndent(m, "", "\t")
return string(data)
}
func SizeSetFixed(size int) SizeChange {
return SizeChange{SetFixed: &size}
}
func SizeSetProportion(size float64) SizeChange {
return SizeChange{SetProportion: &size}
}
func SizeAdjustFixed(size int) SizeChange {
return SizeChange{AdjustFixed: &size}
}
func SizeAdjustProportion(size float64) SizeChange {
return SizeChange{AdjustProportion: &size}
}
const sizePatternString = `^(\+|-)?((\d+?)(?:\.\d+)?)(%)?$`
const sizePatternGroupAdjust = 1
const sizePatternGroupFloatValue = 2
const sizePatternGroupIntValue = 3
const sizePatternGroupPercentage = 4
var sizePattern = regexp.MustCompile(sizePatternString)
func ParseSize(str string) (SizeChange, error) {
matches := sizePattern.FindStringSubmatch(str)
if matches == nil {
return SizeChange{}, fmt.Errorf("invalid size spec '%s'. Expected pattern: %s", str, sizePatternString)
}
adjust := matches[sizePatternGroupAdjust] != ""
proportion := matches[sizePatternGroupPercentage] == "%"
negative := matches[sizePatternGroupAdjust] == "-"
factor := 1
if negative {
factor = -1
}
floatValue, err := strconv.ParseFloat(matches[sizePatternGroupFloatValue], 64)
if err != nil {
return SizeChange{}, fmt.Errorf("invalid size spec '%s'. Expected pattern: %s", str, sizePatternString)
}
intValue, err := strconv.ParseInt(matches[sizePatternGroupIntValue], 10, 64)
if err != nil {
return SizeChange{}, fmt.Errorf("invalid size spec '%s'. Expected pattern: %s", str, sizePatternString)
}
switch true {
case adjust && proportion:
return SizeAdjustProportion(floatValue * float64(factor)), nil
case adjust && !proportion:
return SizeAdjustFixed(int(intValue) * factor), nil
case !adjust && proportion:
return SizeSetProportion(floatValue * float64(factor)), nil
case !adjust && !proportion:
return SizeSetFixed(int(intValue) * factor), nil
default:
return SizeChange{}, fmt.Errorf("invalid size spec '%s'. Expected pattern: %s", str, sizePatternString)
}
}