Files
eway/internal/entity/dimension.go
2024-02-11 15:50:43 +03:00

143 lines
2.9 KiB
Go

package entity
import (
"fmt"
"strconv"
"strings"
)
var DefaultLocale = DimensionLocalRU
type DimensionLocale uint8
const (
DimensionLocalUnspecified DimensionLocale = iota
DimensionLocalRU
dimensionLocalEnd
)
type DimensionKind uint8
func (k DimensionKind) GetPos() float64 {
switch k {
case DimensionKindMilimeter:
return 1
case DimensionKindCentimeter:
return 10
case DimensionKindMeter:
return 1000
default:
return 0
}
}
func (k DimensionKind) String() string {
m := getLocaleKindToStringMap()[DefaultLocale]
return m[k]
}
const (
DimensionKindUnspecified DimensionKind = iota
DimensionKindMilimeter
DimensionKindCentimeter
DimensionKindMeter
)
type Dimension struct {
Value float64
Kind DimensionKind
}
func (d Dimension) MarshalText() ([]byte, error) {
value := strconv.FormatFloat(d.Value, 'f', 4, 64) + " " + d.Kind.String()
return []byte(value), nil
}
func (d *Dimension) UnmarshalText(data []byte) (err error) {
*d, err = ParseDimention(string(data), DefaultLocale)
return err
}
func (d Dimension) AdjustTo(kind DimensionKind) Dimension {
from := d.Kind.GetPos()
to := kind.GetPos()
switch {
case from < to:
mult := to / from
return Dimension{
Kind: kind,
Value: d.Value / float64(mult),
}
case from > to:
mult := from / to
return Dimension{
Kind: kind,
Value: d.Value * float64(mult),
}
}
return d
}
func ParseDimention(value string, locale DimensionLocale) (Dimension, error) {
switch locale {
case DimensionLocalRU:
default:
return Dimension{}, SimpleError("unknown locale for parse")
}
dimensionStrToKind := getLocaleToKindMap()[locale]
lastSpaceIdx := strings.LastIndex(value, " ")
if lastSpaceIdx == -1 {
return Dimension{}, SimpleError("expected 2 values after split for value " + value)
}
var splitted [2]string
splitted[0] = strings.ReplaceAll(value[:lastSpaceIdx], " ", "")
splitted[1] = value[lastSpaceIdx+1:]
var out Dimension
var ok bool
out.Kind, ok = dimensionStrToKind[splitted[1]]
if !ok {
return Dimension{}, SimpleError("dimension map not found for kind " + splitted[1])
}
var err error
out.Value, err = strconv.ParseFloat(splitted[0], 64)
if err != nil {
return Dimension{}, fmt.Errorf("parsing value: %w", err)
}
return out, nil
}
func NewMilimeterDimension(value float64) Dimension {
return Dimension{
Value: value,
Kind: DimensionKindMilimeter,
}
}
func getLocaleToKindMap() map[DimensionLocale]map[string]DimensionKind {
return map[DimensionLocale]map[string]DimensionKind{
DimensionLocalRU: {
"мм": DimensionKindMilimeter,
"см": DimensionKindCentimeter,
"м": DimensionKindMeter,
},
}
}
func getLocaleKindToStringMap() map[DimensionLocale]map[DimensionKind]string {
return map[DimensionLocale]map[DimensionKind]string{
DimensionLocalRU: {
DimensionKindMilimeter: "мм",
DimensionKindCentimeter: "см",
DimensionKindMeter: "м",
},
}
}