@@ -7,253 +7,6 @@ import (
77 "unicode"
88)
99
10- func chompDefault (text string ) string {
11- if strings .HasSuffix (text , "\r \n " ) {
12- return text [:len (text )- 2 ]
13- }
14- if strings .HasSuffix (text , "\n " ) || strings .HasSuffix (text , "\r " ) {
15- return text [:len (text )- 1 ]
16- }
17- return text
18- }
19-
20- func stringRuneIndex (text , needle string , offset int ) int {
21- hayRunes := []rune (text )
22- needleRunes := []rune (needle )
23- if offset < 0 || offset > len (hayRunes ) {
24- return - 1
25- }
26- if len (needleRunes ) == 0 {
27- return offset
28- }
29- limit := len (hayRunes ) - len (needleRunes )
30- if limit < offset {
31- return - 1
32- }
33- for i := offset ; i <= limit ; i ++ {
34- match := true
35- for j := range len (needleRunes ) {
36- if hayRunes [i + j ] != needleRunes [j ] {
37- match = false
38- break
39- }
40- }
41- if match {
42- return i
43- }
44- }
45- return - 1
46- }
47-
48- func stringRuneRIndex (text , needle string , offset int ) int {
49- hayRunes := []rune (text )
50- needleRunes := []rune (needle )
51- if offset < 0 {
52- return - 1
53- }
54- if offset > len (hayRunes ) {
55- offset = len (hayRunes )
56- }
57- if len (needleRunes ) == 0 {
58- return offset
59- }
60- if len (needleRunes ) > len (hayRunes ) {
61- return - 1
62- }
63- start := offset
64- maxStart := len (hayRunes ) - len (needleRunes )
65- if start > maxStart {
66- start = maxStart
67- }
68- for i := start ; i >= 0 ; i -- {
69- match := true
70- for j := range len (needleRunes ) {
71- if hayRunes [i + j ] != needleRunes [j ] {
72- match = false
73- break
74- }
75- }
76- if match {
77- return i
78- }
79- }
80- return - 1
81- }
82-
83- func stringRuneSlice (text string , start , length int ) (string , bool ) {
84- runes := []rune (text )
85- if start < 0 || start >= len (runes ) {
86- return "" , false
87- }
88- if length < 0 {
89- return "" , false
90- }
91- remaining := len (runes ) - start
92- if length >= remaining {
93- return string (runes [start :]), true
94- }
95- end := start + length
96- return string (runes [start :end ]), true
97- }
98-
99- func stringCapitalize (text string ) string {
100- runes := []rune (text )
101- if len (runes ) == 0 {
102- return ""
103- }
104- runes [0 ] = unicode .ToUpper (runes [0 ])
105- for i := 1 ; i < len (runes ); i ++ {
106- runes [i ] = unicode .ToLower (runes [i ])
107- }
108- return string (runes )
109- }
110-
111- func stringSwapCase (text string ) string {
112- runes := []rune (text )
113- for i , r := range runes {
114- if unicode .IsUpper (r ) {
115- runes [i ] = unicode .ToLower (r )
116- continue
117- }
118- if unicode .IsLower (r ) {
119- runes [i ] = unicode .ToUpper (r )
120- }
121- }
122- return string (runes )
123- }
124-
125- func stringReverse (text string ) string {
126- runes := []rune (text )
127- for i , j := 0 , len (runes )- 1 ; i < j ; i , j = i + 1 , j - 1 {
128- runes [i ], runes [j ] = runes [j ], runes [i ]
129- }
130- return string (runes )
131- }
132-
133- func stringRegexOption (method string , kwargs map [string ]Value ) (bool , error ) {
134- if len (kwargs ) == 0 {
135- return false , nil
136- }
137- regexVal , ok := kwargs ["regex" ]
138- if ! ok || len (kwargs ) > 1 {
139- return false , fmt .Errorf ("string.%s supports only regex keyword" , method )
140- }
141- if regexVal .Kind () != KindBool {
142- return false , fmt .Errorf ("string.%s regex keyword must be bool" , method )
143- }
144- return regexVal .Bool (), nil
145- }
146-
147- func stringSub (text , pattern , replacement string , regex bool ) (string , error ) {
148- if ! regex {
149- return strings .Replace (text , pattern , replacement , 1 ), nil
150- }
151- re , err := regexp .Compile (pattern )
152- if err != nil {
153- return "" , err
154- }
155- loc := re .FindStringSubmatchIndex (text )
156- if loc == nil {
157- return text , nil
158- }
159- replaced := re .ExpandString (nil , replacement , text , loc )
160- return text [:loc [0 ]] + string (replaced ) + text [loc [1 ]:], nil
161- }
162-
163- func stringGSub (text , pattern , replacement string , regex bool ) (string , error ) {
164- if ! regex {
165- return strings .ReplaceAll (text , pattern , replacement ), nil
166- }
167- re , err := regexp .Compile (pattern )
168- if err != nil {
169- return "" , err
170- }
171- return re .ReplaceAllString (text , replacement ), nil
172- }
173-
174- func stringBangResult (original , updated string ) Value {
175- if updated == original {
176- return NewNil ()
177- }
178- return NewString (updated )
179- }
180-
181- func stringSquish (text string ) string {
182- return strings .Join (strings .Fields (text ), " " )
183- }
184-
185- func stringTemplateOption (kwargs map [string ]Value ) (bool , error ) {
186- if len (kwargs ) == 0 {
187- return false , nil
188- }
189- value , ok := kwargs ["strict" ]
190- if ! ok || len (kwargs ) != 1 {
191- return false , fmt .Errorf ("string.template supports only strict keyword" )
192- }
193- if value .Kind () != KindBool {
194- return false , fmt .Errorf ("string.template strict keyword must be bool" )
195- }
196- return value .Bool (), nil
197- }
198-
199- func stringTemplateLookup (context Value , keyPath string ) (Value , bool ) {
200- current := context
201- for _ , segment := range strings .Split (keyPath , "." ) {
202- if segment == "" {
203- return NewNil (), false
204- }
205- if current .Kind () != KindHash && current .Kind () != KindObject {
206- return NewNil (), false
207- }
208- next , ok := current .Hash ()[segment ]
209- if ! ok {
210- return NewNil (), false
211- }
212- current = next
213- }
214- return current , true
215- }
216-
217- func stringTemplateScalarValue (value Value , keyPath string ) (string , error ) {
218- switch value .Kind () {
219- case KindNil , KindBool , KindInt , KindFloat , KindString , KindSymbol , KindMoney , KindDuration , KindTime :
220- return value .String (), nil
221- default :
222- return "" , fmt .Errorf ("string.template placeholder %s value must be scalar" , keyPath )
223- }
224- }
225-
226- func stringTemplate (text string , context Value , strict bool ) (string , error ) {
227- templateErr := error (nil )
228- rendered := stringTemplatePattern .ReplaceAllStringFunc (text , func (match string ) string {
229- if templateErr != nil {
230- return match
231- }
232- submatch := stringTemplatePattern .FindStringSubmatch (match )
233- if len (submatch ) != 2 {
234- return match
235- }
236- keyPath := submatch [1 ]
237- value , ok := stringTemplateLookup (context , keyPath )
238- if ! ok {
239- if strict {
240- templateErr = fmt .Errorf ("string.template missing placeholder %s" , keyPath )
241- }
242- return match
243- }
244- segment , err := stringTemplateScalarValue (value , keyPath )
245- if err != nil {
246- templateErr = err
247- return match
248- }
249- return segment
250- })
251- if templateErr != nil {
252- return "" , templateErr
253- }
254- return rendered , nil
255- }
256-
25710func stringMember (str Value , property string ) (Value , error ) {
25811 switch property {
25912 case "size" :
0 commit comments