...

Source file src/cuelang.org/go/pkg/strings/manual.go

Documentation: cuelang.org/go/pkg/strings

     1  // Copyright 2018 The CUE Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package strings implements simple functions to manipulate UTF-8 encoded
    16  // strings.package strings.
    17  //
    18  // Some of the functions in this package are specifically intended as field
    19  // constraints. For instance, MaxRunes as used in this CUE program
    20  //
    21  //	import "strings"
    22  //
    23  //	myString: strings.MaxRunes(5)
    24  //
    25  // specifies that the myString should be at most 5 code points.
    26  package strings
    27  
    28  import (
    29  	"fmt"
    30  	"strings"
    31  	"unicode"
    32  )
    33  
    34  // ByteAt reports the ith byte of the underlying strings or byte.
    35  func ByteAt(b []byte, i int) (byte, error) {
    36  	if i < 0 || i >= len(b) {
    37  		return 0, fmt.Errorf("index out of range")
    38  	}
    39  	return b[i], nil
    40  }
    41  
    42  // ByteSlice reports the bytes of the underlying string data from the start
    43  // index up to but not including the end index.
    44  func ByteSlice(b []byte, start, end int) ([]byte, error) {
    45  	if start < 0 || start > end || end > len(b) {
    46  		return nil, fmt.Errorf("index out of range")
    47  	}
    48  	return b[start:end], nil
    49  }
    50  
    51  // Runes returns the Unicode code points of the given string.
    52  func Runes(s string) []rune {
    53  	return []rune(s)
    54  }
    55  
    56  // MinRunes reports whether the number of runes (Unicode codepoints) in a string
    57  // is at least a certain minimum. MinRunes can be used a field constraint to
    58  // except all strings for which this property holds.
    59  func MinRunes(s string, min int) bool {
    60  	// TODO: CUE strings cannot be invalid UTF-8. In case this changes, we need
    61  	// to use the following conversion to count properly:
    62  	// s, _ = unicodeenc.UTF8.NewDecoder().String(s)
    63  	return len([]rune(s)) >= min
    64  }
    65  
    66  // MaxRunes reports whether the number of runes (Unicode codepoints) in a string
    67  // exceeds a certain maximum. MaxRunes can be used a field constraint to
    68  // except all strings for which this property holds
    69  func MaxRunes(s string, max int) bool {
    70  	// See comment in MinRunes implementation.
    71  	return len([]rune(s)) <= max
    72  }
    73  
    74  // ToTitle returns a copy of the string s with all Unicode letters that begin
    75  // words mapped to their title case.
    76  func ToTitle(s string) string {
    77  	// Use a closure here to remember state.
    78  	// Hackish but effective. Depends on Map scanning in order and calling
    79  	// the closure once per rune.
    80  	prev := ' '
    81  	return strings.Map(
    82  		func(r rune) rune {
    83  			if unicode.IsSpace(prev) {
    84  				prev = r
    85  				return unicode.ToTitle(r)
    86  			}
    87  			prev = r
    88  			return r
    89  		},
    90  		s)
    91  }
    92  
    93  // ToCamel returns a copy of the string s with all Unicode letters that begin
    94  // words mapped to lower case.
    95  func ToCamel(s string) string {
    96  	// Use a closure here to remember state.
    97  	// Hackish but effective. Depends on Map scanning in order and calling
    98  	// the closure once per rune.
    99  	prev := ' '
   100  	return strings.Map(
   101  		func(r rune) rune {
   102  			if unicode.IsSpace(prev) {
   103  				prev = r
   104  				return unicode.ToLower(r)
   105  			}
   106  			prev = r
   107  			return r
   108  		},
   109  		s)
   110  }
   111  
   112  // SliceRunes returns a string of the underlying string data from the start index
   113  // up to but not including the end index.
   114  func SliceRunes(s string, start, end int) (string, error) {
   115  	runes := []rune(s)
   116  	if start < 0 || start > end || end > len(runes) {
   117  		return "", fmt.Errorf("index out of range")
   118  	}
   119  	return string(runes[start:end]), nil
   120  }
   121  

View as plain text