Skip to content

Commit e551985

Browse files
committed
extract string member helper routines
1 parent 7760b29 commit e551985

2 files changed

Lines changed: 255 additions & 247 deletions

File tree

vibes/execution_members_string.go

Lines changed: 0 additions & 247 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
25710
func stringMember(str Value, property string) (Value, error) {
25811
switch property {
25912
case "size":

0 commit comments

Comments
 (0)