ParseString parse string with variables
(raw string, variablesMapping map[string]interface{})
| 170 | |
| 171 | // ParseString parse string with variables |
| 172 | func (p *Parser) ParseString(raw string, variablesMapping map[string]interface{}) (interface{}, error) { |
| 173 | matchStartPosition := 0 |
| 174 | parsedString := "" |
| 175 | remainedString := raw |
| 176 | |
| 177 | for matchStartPosition < len(raw) { |
| 178 | // locate $ char position |
| 179 | startPosition := strings.Index(remainedString, "$") |
| 180 | if startPosition == -1 { // no $ found |
| 181 | // append remained string |
| 182 | parsedString += remainedString |
| 183 | break |
| 184 | } |
| 185 | |
| 186 | // found $, check if variable or function |
| 187 | matchStartPosition += startPosition |
| 188 | parsedString += remainedString[0:startPosition] |
| 189 | remainedString = remainedString[startPosition:] |
| 190 | |
| 191 | // Notice: notation priority |
| 192 | // $$ > ${func($a, $b)} > $var |
| 193 | |
| 194 | // search $$, use $$ to escape $ notation |
| 195 | if strings.HasPrefix(remainedString, "$$") { // found $$ |
| 196 | matchStartPosition += 2 |
| 197 | parsedString += "$" |
| 198 | remainedString = remainedString[2:] |
| 199 | continue |
| 200 | } |
| 201 | |
| 202 | // search function like ${func($a, $b)} |
| 203 | funcMatched := regexCompileFunction.FindStringSubmatch(remainedString) |
| 204 | if len(funcMatched) == 3 { |
| 205 | funcName := funcMatched[1] |
| 206 | argsStr := funcMatched[2] |
| 207 | arguments, err := parseFunctionArguments(argsStr) |
| 208 | if err != nil { |
| 209 | return raw, errors.Wrap(code.ParseFunctionError, err.Error()) |
| 210 | } |
| 211 | parsedArgs, err := p.Parse(arguments, variablesMapping) |
| 212 | if err != nil { |
| 213 | return raw, err |
| 214 | } |
| 215 | |
| 216 | result, err := p.callFunc(funcName, parsedArgs.([]interface{})...) |
| 217 | if err != nil { |
| 218 | log.Error().Str("funcName", funcName).Interface("arguments", arguments). |
| 219 | Err(err).Msg("call function failed") |
| 220 | return raw, errors.Wrap(code.CallFunctionError, err.Error()) |
| 221 | } |
| 222 | log.Info().Str("funcName", funcName).Interface("arguments", arguments). |
| 223 | Interface("output", result).Msg("call function success") |
| 224 | |
| 225 | if funcMatched[0] == raw { |
| 226 | // raw_string is a function, e.g. "${add_one(3)}", return its eval value directly |
| 227 | return result, nil |
| 228 | } |
| 229 |
no test coverage detected