summaryrefslogtreecommitdiff
path: root/format.go
blob: 43693148504c75206c068fac5a63ebdba87248fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package float

import (
	"strconv"
	"strings"
)

func split(s string, n int) []string {
	ret := make([]string, 0, len(s)/n+1)
	var pos int
	if rest := len(s) % n; rest > 0 {
		ret = append(ret, s[:rest])
		pos = rest
	}
	for pos < len(s) {
		ret = append(ret, s[pos:pos+n])
		pos += n
	}
	return ret
}

func fill(s string, n int) string {
	if len(s) >= n {
		return s[:n]
	}
	return s + strings.Repeat("0", n-len(s))
}

// Country settings
type Country struct {
	Thousend, Decimal, Neg string // delimiter
	Block, Fraction        int    // length
}

const (
	Neg          = "-"
	Space        = " "
	Apostrophe   = "'"
	Comma        = ","
	FullStop     = "."
	MiddleDot    = "\u00b7"
	ThinSpace    = "\u2009"
	NoBreakSpace = "\u202f"
	DotAbove     = "\u02d9"
)

var (
	EN = Country{Space, FullStop, Neg, 3, 2} // SI EN
	FR = Country{Space, Comma, Neg, 3, 2}    // SI FR
	US = Country{Comma, FullStop, Neg, 3, 2}
	DE = Country{FullStop, Comma, Neg, 3, 2}
	IR = Country{Space, MiddleDot, Neg, 3, 2}
	CH = Country{Apostrophe, FullStop, Neg, 3, 2}
	IT = Country{DotAbove, Comma, Neg, 3, 2}
	CN = Country{Comma, FullStop, Neg, 4, 2} // 10000 based
)

// DefaultFormat is europeian SI format
var DefaultFormat = FR

// Format float value as localized representation
func (c Country) Format(v float64) string {
	s := strconv.FormatFloat(v, 'f', -1, 64)
	neg := strings.HasPrefix(s, Neg)
	if neg {
		s = s[1:] // stip neg
	}
	// add extra dot for there will be at least 2 parts
	parts := strings.Split(s+FullStop, FullStop)
	lhs := split(parts[0], c.Block)
	s = strings.Join(lhs, c.Thousend)
	if neg {
		s = c.Neg + s // rejoin neg
	}
	rhs := fill(parts[1], c.Fraction)
	return s + c.Decimal + rhs
}

// Format float with default format
func Format(v float64) string {
	return DefaultFormat.Format(v)
}