github.com/MontFerret/ferret@v0.18.0/pkg/stdlib/strings/substr.go (about)

     1  package strings
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/MontFerret/ferret/pkg/runtime/core"
     7  	"github.com/MontFerret/ferret/pkg/runtime/values"
     8  	"github.com/MontFerret/ferret/pkg/runtime/values/types"
     9  )
    10  
    11  // SUBSTRING returns a substring of value.
    12  // @param {String} str - The source string.
    13  // @param {Int} offset - Start at offset, offsets start at position 0.
    14  // @param {Int} [length] - At most length characters, omit to get the substring from offset to the end of the string.
    15  // @return {String} - A substring of value.
    16  func Substring(_ context.Context, args ...core.Value) (core.Value, error) {
    17  	err := core.ValidateArgs(args, 2, 3)
    18  
    19  	if err != nil {
    20  		return values.EmptyString, err
    21  	}
    22  
    23  	err = core.ValidateType(args[1], types.Int)
    24  
    25  	if err != nil {
    26  		return values.EmptyString, err
    27  	}
    28  
    29  	text := args[0].String()
    30  	runes := []rune(text)
    31  	size := len(runes)
    32  	offset := int(args[1].(values.Int))
    33  	length := size
    34  
    35  	if len(args) > 2 {
    36  		if args[2].Type() == types.Int {
    37  			length = int(args[2].(values.Int))
    38  		}
    39  	}
    40  
    41  	var substr []rune
    42  
    43  	if length == size {
    44  		substr = runes[offset:]
    45  	} else {
    46  		end := offset + length
    47  
    48  		if size > end {
    49  			substr = runes[offset:end]
    50  		} else {
    51  			substr = runes[offset:]
    52  		}
    53  	}
    54  
    55  	return values.NewStringFromRunes(substr), nil
    56  }
    57  
    58  // LEFT returns the leftmost characters of the string value by index.
    59  // @param {String} str - The source string.
    60  // @param {Int} length - The amount of characters to return.
    61  // @return {String} - The leftmost characters of the string value by index.
    62  func Left(_ context.Context, args ...core.Value) (core.Value, error) {
    63  	err := core.ValidateArgs(args, 2, 2)
    64  
    65  	if err != nil {
    66  		return values.EmptyString, err
    67  	}
    68  
    69  	text := args[0].String()
    70  	runes := []rune(text)
    71  
    72  	var pos int
    73  
    74  	if args[1].Type() == types.Int {
    75  		pos = int(args[1].(values.Int))
    76  	}
    77  
    78  	if len(text) < pos {
    79  		return values.NewString(text), nil
    80  	}
    81  
    82  	return values.NewStringFromRunes(runes[0:pos]), nil
    83  }
    84  
    85  // RIGHT returns the rightmost characters of the string value.
    86  // @param {String} str - The source string.
    87  // @param {Int} length - The amount of characters to return.
    88  // @return {String} - The rightmost characters of the string value.
    89  func Right(_ context.Context, args ...core.Value) (core.Value, error) {
    90  	err := core.ValidateArgs(args, 2, 2)
    91  
    92  	if err != nil {
    93  		return values.EmptyString, err
    94  	}
    95  
    96  	text := args[0].String()
    97  	runes := []rune(text)
    98  	size := len(runes)
    99  	pos := size
   100  
   101  	if args[1].Type() == types.Int {
   102  		pos = int(args[1].(values.Int))
   103  	}
   104  
   105  	if len(text) < pos {
   106  		return values.NewString(text), nil
   107  	}
   108  
   109  	return values.NewStringFromRunes(runes[size-pos : size]), nil
   110  }