-
Notifications
You must be signed in to change notification settings - Fork 1
/
strmask.go
87 lines (71 loc) · 1.82 KB
/
strmask.go
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
83
84
85
86
87
package strmask
import (
"errors"
"unicode"
)
const (
LetterDigit = '#'
Digit = '0'
LowerLetterDigit = 'L'
LowerLetter = 'l'
UpperLetterDigit = 'U'
UpperLetter = 'u'
)
var ErrValue = errors.New("invalid value")
func Apply(mask, value string) (string, error) {
valueRunes := []rune(value)
runes := make([]rune, 0, len(mask))
cursor := 0
var r rune
for _, mT := range mask {
if isMaskType(mT) {
r = getRune(mT, valueRunes, &cursor)
if r == -1 {
return string(runes), ErrValue
}
} else {
r = mT
}
runes = append(runes, r)
}
return string(runes), nil
}
func getRune(maskType rune, value []rune, cursor *int) rune {
if (*cursor) > len(value)-1 {
return -1
}
r := value[*cursor]
*cursor++
// # - Requires a unicode letter or digit at this position
// 0 - Requires a digit at this position
if (maskType == LetterDigit && isLetterOrDigit(r)) || (maskType == Digit && unicode.IsDigit(r)) {
return r
}
// L - Requires a unicode letter (will be lower) or digit at this position
// l - Requires a unicode letter (will be lower) at this position
if (maskType == LowerLetterDigit && isLetterOrDigit(r)) || (maskType == LowerLetter && unicode.IsLetter(r)) {
return unicode.ToLower(r)
}
// U - Requires a unicode letter (will be upper) or digit at this position
// u - Requires a unicode letter (will be upper) at this position
if (maskType == UpperLetterDigit && isLetterOrDigit(r)) || (maskType == UpperLetter && unicode.IsLetter(r)) {
return unicode.ToUpper(r)
}
return getRune(maskType, value, cursor)
}
func isLetterOrDigit(r rune) bool {
return unicode.IsLetter(r) || unicode.IsDigit(r)
}
func isMaskType(r rune) bool {
switch r {
case LetterDigit,
Digit,
LowerLetterDigit,
LowerLetter,
UpperLetterDigit,
UpperLetter:
return true
default:
return false
}
}