apps/habbits/validate.go 1.3 K raw
1
package main
2
3
import (
4
	"fmt"
5
	"strconv"
6
	"strings"
7
)
8
9
// normalizeValue validates raw against the habit's declared value type and
10
// returns the canonical stored form. The server is the source of truth; the
11
// UI widgets are only a convenience.
12
func normalizeValue(valueType, raw string) (string, error) {
13
	raw = strings.TrimSpace(raw)
14
	switch valueType {
15
	case "int":
16
		n, err := strconv.ParseInt(raw, 10, 64)
17
		if err != nil {
18
			return "", fmt.Errorf("value must be a whole number")
19
		}
20
		return strconv.FormatInt(n, 10), nil
21
	case "float":
22
		f, err := strconv.ParseFloat(raw, 64)
23
		if err != nil {
24
			return "", fmt.Errorf("value must be a number")
25
		}
26
		return strconv.FormatFloat(f, 'f', -1, 64), nil
27
	case "bool":
28
		switch strings.ToLower(raw) {
29
		case "true", "1", "on", "yes", "y":
30
			return "true", nil
31
		case "false", "0", "off", "no", "n":
32
			return "false", nil
33
		default:
34
			return "", fmt.Errorf("value must be true or false")
35
		}
36
	case "string":
37
		if raw == "" {
38
			return "", fmt.Errorf("value is required")
39
		}
40
		return raw, nil
41
	default:
42
		return "", fmt.Errorf("unknown value type %q", valueType)
43
	}
44
}
45
46
// validValueType reports whether t is one of the allowed habit value types.
47
func validValueType(t string) bool {
48
	for _, v := range valueTypes {
49
		if v == t {
50
			return true
51
		}
52
	}
53
	return false
54
}