84 lines
2.3 KiB
Go
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)
|
|
}
|
|
}
|