-
Notifications
You must be signed in to change notification settings - Fork 19
/
text.go
109 lines (88 loc) · 2.66 KB
/
text.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package types
import (
"fmt"
"strings"
"unicode/utf8"
"github.com/nyaruka/goflow/envs"
"github.com/nyaruka/goflow/utils"
"github.com/nyaruka/goflow/utils/jsonx"
)
// XText is a string of characters.
//
// @("abc") -> abc
// @(text_length("abc")) -> 3
// @(upper("abc")) -> ABC
// @(json("abc")) -> "abc"
//
// @type text
type XText struct {
native string
}
// NewXText creates a new text value
func NewXText(value string) XText {
return XText{native: value}
}
// Describe returns a representation of this type for error messages
func (x XText) Describe() string { return fmt.Sprintf(`"%s"`, x.Native()) }
// Truthy determines truthiness for this type
func (x XText) Truthy() bool {
return !x.Empty() && strings.ToLower(x.Native()) != "false"
}
// Render returns the canonical text representation
func (x XText) Render() string { return x.Native() }
// Format returns the pretty text representation
func (x XText) Format(env envs.Environment) string {
return x.Render()
}
// String returns the native string representation of this type for debugging
func (x XText) String() string { return `XText("` + x.Native() + `")` }
// Native returns the native value of this type
func (x XText) Native() string { return x.native }
// Equals determines equality for this type
func (x XText) Equals(other XText) bool {
return x.Native() == other.Native()
}
// Compare compares this string to another
func (x XText) Compare(other XText) int {
return strings.Compare(x.Native(), other.Native())
}
// Slice returns a substring of this text
func (x XText) Slice(start, end int) XText {
length := x.Length()
if start < 0 {
start = 0
}
if end > length {
end = length
}
if start >= length || end < start {
return XTextEmpty
}
runes := []rune(x.native)[start:end]
return NewXText(string(runes))
}
// Length returns the length of this string
func (x XText) Length() int { return utf8.RuneCountInString(x.Native()) }
// Empty returns whether this is an empty string
func (x XText) Empty() bool { return x.Native() == "" }
// MarshalJSON is called when a struct containing this type is marshaled
func (x XText) MarshalJSON() ([]byte, error) {
return jsonx.Marshal(x.Native())
}
// UnmarshalJSON is called when a struct containing this type is unmarshaled
func (x *XText) UnmarshalJSON(data []byte) error {
return jsonx.Unmarshal(data, &x.native)
}
// XTextEmpty is the empty text value
var XTextEmpty = NewXText("")
var _ XValue = XTextEmpty
// ToXText converts the given value to a string
func ToXText(env envs.Environment, x XValue) (XText, XError) {
if utils.IsNil(x) {
return XTextEmpty, nil
}
if IsXError(x) {
return XTextEmpty, x.(XError)
}
return NewXText(x.Render()), nil
}