github.com/MontFerret/ferret@v0.18.0/pkg/runtime/values/string.go (about) 1 package values 2 3 import ( 4 "fmt" 5 "hash/fnv" 6 "strings" 7 8 "github.com/wI2L/jettison" 9 10 "github.com/MontFerret/ferret/pkg/runtime/core" 11 "github.com/MontFerret/ferret/pkg/runtime/values/types" 12 ) 13 14 type String string 15 16 const ( 17 EmptyString = String("") 18 SpaceString = String(" ") 19 ) 20 21 func NewString(input string) String { 22 if input == "" { 23 return EmptyString 24 } 25 26 return String(input) 27 } 28 29 func NewStringFromRunes(input []rune) String { 30 if len(input) == 0 { 31 return EmptyString 32 } 33 34 return String(input) 35 } 36 37 func ParseString(input interface{}) (String, error) { 38 if core.IsNil(input) { 39 return EmptyString, nil 40 } 41 42 str, ok := input.(string) 43 44 if ok { 45 if str != "" { 46 return String(str), nil 47 } 48 49 return EmptyString, nil 50 } 51 52 stringer, ok := input.(fmt.Stringer) 53 54 if ok { 55 return String(stringer.String()), nil 56 } 57 58 return EmptyString, core.Error(core.ErrInvalidType, "expected 'string'") 59 } 60 61 func MustParseString(input interface{}) String { 62 res, err := ParseString(input) 63 64 if err != nil { 65 panic(err) 66 } 67 68 return res 69 } 70 71 func (t String) MarshalJSON() ([]byte, error) { 72 return jettison.MarshalOpts(string(t), jettison.NoHTMLEscaping()) 73 } 74 75 func (t String) Type() core.Type { 76 return types.String 77 } 78 79 func (t String) String() string { 80 return string(t) 81 } 82 83 func (t String) Compare(other core.Value) int64 { 84 if other.Type() == types.String { 85 return int64(strings.Compare(string(t), other.Unwrap().(string))) 86 } 87 88 return types.Compare(types.String, other.Type()) 89 } 90 91 func (t String) Unwrap() interface{} { 92 return string(t) 93 } 94 95 func (t String) Hash() uint64 { 96 h := fnv.New64a() 97 98 h.Write([]byte(t.Type().String())) 99 h.Write([]byte(":")) 100 h.Write([]byte(t)) 101 102 return h.Sum64() 103 } 104 105 func (t String) Copy() core.Value { 106 return t 107 } 108 109 func (t String) Length() Int { 110 return Int(len([]rune(string(t)))) 111 } 112 113 func (t String) Contains(other String) Boolean { 114 return t.IndexOf(other) > -1 115 } 116 117 func (t String) IndexOf(other String) Int { 118 return Int(strings.Index(string(t), string(other))) 119 } 120 121 func (t String) Concat(other core.Value) String { 122 return String(string(t) + other.String()) 123 } 124 125 func (t String) At(index Int) String { 126 return String([]rune(t)[index]) 127 }