all repos

clerk @ 2298caf

missing tooling for ledger/hledger

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

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
printer: add commodity-space option, 13 days 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.CommodityPosAfter
47
		case strings.EqualFold(c, "before"):
48
			s.Format.CommodityPos = printer.CommodityPosBefore
49
		default:
50
			return nil, fmt.Errorf("invalid value %q (want %q or %q)", c, "after", "before")
51
		}
52
	case "commodity_space":
53
		c, ok := val.(string)
54
		if !ok {
55
			return nil, fmt.Errorf("invalid value %v (want string)", val)
56
		}
57
		switch {
58
		case strings.EqualFold(c, "preserve"):
59
			s.Format.CommoditySpace = printer.CommoditySpacePreserve
60
		case strings.EqualFold(c, "always"):
61
			s.Format.CommoditySpace = printer.CommoditySpaceAlways
62
		case strings.EqualFold(c, "never"):
63
			s.Format.CommoditySpace = printer.CommoditySpaceNever
64
		default:
65
			return nil, fmt.Errorf("invalid value %q (want %q, %q or %q)", c, "preserve", "always", "never")
66
		}
67
	default:
68
		return []string{fmt.Sprintf("unknown format option %q", name)}, nil
69
	}
70
	return nil, nil
71
}
72
73
func setInt(n *int, v any, lo, hi int) error {
74
	var x int
75
	switch t := v.(type) {
76
	case int:
77
		x = t
78
	case int64:
79
		x = int(t)
80
	case float64:
81
		if t != float64(int(t)) {
82
			return fmt.Errorf("invalid value %v (want int)", v)
83
		}
84
		x = int(t)
85
	default:
86
		return fmt.Errorf("invalid value %v (want int)", v)
87
	}
88
	if x < lo || x > hi {
89
		return fmt.Errorf("%d out of range (want %d..%d)", x, lo, hi)
90
	}
91
	*n = x
92
	return nil
93
}
94
95
func setBool(b *bool, v any) error {
96
	x, ok := v.(bool)
97
	if !ok {
98
		return fmt.Errorf("invalid value %v (want bool)", v)
99
	}
100
	*b = x
101
	return nil
102
}