all repos

clerk @ c958816

missing tooling for ledger/hledger

clerk/internal/settings/format.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
feat: config (#6), 1 month ago
1
package settings
2
3
import (
4
	"fmt"
5
	"strings"
6
7
	"olexsmir.xyz/clerk/journal/printer"
8
)
9
10
func (s *Settings) setFormat(v any) ([]string, error) {
11
	return applyTable(v, s.setFormatField)
12
}
13
14
func (s *Settings) setFormatField(name string, val any) ([]string, error) {
15
	switch normalizeKey(name) {
16
	case "tab_indent":
17
		return nil, setBool(&s.Format.TabIndent, val)
18
	case "indent_width":
19
		return nil, setInt(&s.Format.IndentWidth, val, 1, 32)
20
	case "preserve_blank_lines":
21
		return nil, setBool(&s.Format.PreserveBlankLines, val)
22
	case "align_style":
23
		as, ok := val.(string)
24
		if !ok {
25
			return nil, fmt.Errorf("invalid value %v (want string)", val)
26
		}
27
		switch {
28
		case strings.EqualFold(as, "two-spaces"):
29
			s.Format.AlignStyle = printer.AlignTwoSpaces
30
		case strings.EqualFold(as, "right"):
31
			s.Format.AlignStyle = printer.AlignRight
32
		case strings.EqualFold(as, "tab"):
33
			s.Format.AlignStyle = printer.AlignTab
34
		default:
35
			return nil, fmt.Errorf("invalid value %q (want %q, %q, or %q)", as, "two-spaces", "right", "tab")
36
		}
37
	case "align_column":
38
		return nil, setInt(&s.Format.AlignColumn, val, 1, 240)
39
	case "commodity_pos":
40
		c, ok := val.(string)
41
		if !ok {
42
			return nil, fmt.Errorf("invalid value %v (want string)", val)
43
		}
44
		switch {
45
		case strings.EqualFold(c, "after"):
46
			s.Format.CommodityPos = printer.CommodityAfter
47
		case strings.EqualFold(c, "before"):
48
			s.Format.CommodityPos = printer.CommodityBefore
49
		default:
50
			return nil, fmt.Errorf("invalid value %q (want %q or %q)", c, "after", "before")
51
		}
52
	default:
53
		return []string{fmt.Sprintf("unknown format option %q", name)}, nil
54
	}
55
	return nil, nil
56
}
57
58
func setInt(n *int, v any, lo, hi int) error {
59
	var x int
60
	switch t := v.(type) {
61
	case int:
62
		x = t
63
	case int64:
64
		x = int(t)
65
	case float64:
66
		if t != float64(int(t)) {
67
			return fmt.Errorf("invalid value %v (want int)", v)
68
		}
69
		x = int(t)
70
	default:
71
		return fmt.Errorf("invalid value %v (want int)", v)
72
	}
73
	if x < lo || x > hi {
74
		return fmt.Errorf("%d out of range (want %d..%d)", x, lo, hi)
75
	}
76
	*n = x
77
	return nil
78
}
79
80
func setBool(b *bool, v any) error {
81
	x, ok := v.(bool)
82
	if !ok {
83
		return fmt.Errorf("invalid value %v (want bool)", v)
84
	}
85
	*b = x
86
	return nil
87
}