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  }