functions.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. package jmespath
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "math"
  7. "reflect"
  8. "sort"
  9. "strconv"
  10. "strings"
  11. "unicode/utf8"
  12. )
  13. type jpFunction func(arguments []interface{}) (interface{}, error)
  14. type jpType string
  15. const (
  16. jpUnknown jpType = "unknown"
  17. jpNumber jpType = "number"
  18. jpString jpType = "string"
  19. jpArray jpType = "array"
  20. jpObject jpType = "object"
  21. jpArrayNumber jpType = "array[number]"
  22. jpArrayString jpType = "array[string]"
  23. jpExpref jpType = "expref"
  24. jpAny jpType = "any"
  25. )
  26. type functionEntry struct {
  27. name string
  28. arguments []argSpec
  29. handler jpFunction
  30. hasExpRef bool
  31. }
  32. type argSpec struct {
  33. types []jpType
  34. variadic bool
  35. }
  36. type byExprString struct {
  37. intr *treeInterpreter
  38. node ASTNode
  39. items []interface{}
  40. hasError bool
  41. }
  42. func (a *byExprString) Len() int {
  43. return len(a.items)
  44. }
  45. func (a *byExprString) Swap(i, j int) {
  46. a.items[i], a.items[j] = a.items[j], a.items[i]
  47. }
  48. func (a *byExprString) Less(i, j int) bool {
  49. first, err := a.intr.Execute(a.node, a.items[i])
  50. if err != nil {
  51. a.hasError = true
  52. // Return a dummy value.
  53. return true
  54. }
  55. ith, ok := first.(string)
  56. if !ok {
  57. a.hasError = true
  58. return true
  59. }
  60. second, err := a.intr.Execute(a.node, a.items[j])
  61. if err != nil {
  62. a.hasError = true
  63. // Return a dummy value.
  64. return true
  65. }
  66. jth, ok := second.(string)
  67. if !ok {
  68. a.hasError = true
  69. return true
  70. }
  71. return ith < jth
  72. }
  73. type byExprFloat struct {
  74. intr *treeInterpreter
  75. node ASTNode
  76. items []interface{}
  77. hasError bool
  78. }
  79. func (a *byExprFloat) Len() int {
  80. return len(a.items)
  81. }
  82. func (a *byExprFloat) Swap(i, j int) {
  83. a.items[i], a.items[j] = a.items[j], a.items[i]
  84. }
  85. func (a *byExprFloat) Less(i, j int) bool {
  86. first, err := a.intr.Execute(a.node, a.items[i])
  87. if err != nil {
  88. a.hasError = true
  89. // Return a dummy value.
  90. return true
  91. }
  92. ith, ok := first.(float64)
  93. if !ok {
  94. a.hasError = true
  95. return true
  96. }
  97. second, err := a.intr.Execute(a.node, a.items[j])
  98. if err != nil {
  99. a.hasError = true
  100. // Return a dummy value.
  101. return true
  102. }
  103. jth, ok := second.(float64)
  104. if !ok {
  105. a.hasError = true
  106. return true
  107. }
  108. return ith < jth
  109. }
  110. type functionCaller struct {
  111. functionTable map[string]functionEntry
  112. }
  113. func newFunctionCaller() *functionCaller {
  114. caller := &functionCaller{}
  115. caller.functionTable = map[string]functionEntry{
  116. "length": {
  117. name: "length",
  118. arguments: []argSpec{
  119. {types: []jpType{jpString, jpArray, jpObject}},
  120. },
  121. handler: jpfLength,
  122. },
  123. "starts_with": {
  124. name: "starts_with",
  125. arguments: []argSpec{
  126. {types: []jpType{jpString}},
  127. {types: []jpType{jpString}},
  128. },
  129. handler: jpfStartsWith,
  130. },
  131. "abs": {
  132. name: "abs",
  133. arguments: []argSpec{
  134. {types: []jpType{jpNumber}},
  135. },
  136. handler: jpfAbs,
  137. },
  138. "avg": {
  139. name: "avg",
  140. arguments: []argSpec{
  141. {types: []jpType{jpArrayNumber}},
  142. },
  143. handler: jpfAvg,
  144. },
  145. "ceil": {
  146. name: "ceil",
  147. arguments: []argSpec{
  148. {types: []jpType{jpNumber}},
  149. },
  150. handler: jpfCeil,
  151. },
  152. "contains": {
  153. name: "contains",
  154. arguments: []argSpec{
  155. {types: []jpType{jpArray, jpString}},
  156. {types: []jpType{jpAny}},
  157. },
  158. handler: jpfContains,
  159. },
  160. "ends_with": {
  161. name: "ends_with",
  162. arguments: []argSpec{
  163. {types: []jpType{jpString}},
  164. {types: []jpType{jpString}},
  165. },
  166. handler: jpfEndsWith,
  167. },
  168. "floor": {
  169. name: "floor",
  170. arguments: []argSpec{
  171. {types: []jpType{jpNumber}},
  172. },
  173. handler: jpfFloor,
  174. },
  175. "map": {
  176. name: "amp",
  177. arguments: []argSpec{
  178. {types: []jpType{jpExpref}},
  179. {types: []jpType{jpArray}},
  180. },
  181. handler: jpfMap,
  182. hasExpRef: true,
  183. },
  184. "max": {
  185. name: "max",
  186. arguments: []argSpec{
  187. {types: []jpType{jpArrayNumber, jpArrayString}},
  188. },
  189. handler: jpfMax,
  190. },
  191. "merge": {
  192. name: "merge",
  193. arguments: []argSpec{
  194. {types: []jpType{jpObject}, variadic: true},
  195. },
  196. handler: jpfMerge,
  197. },
  198. "max_by": {
  199. name: "max_by",
  200. arguments: []argSpec{
  201. {types: []jpType{jpArray}},
  202. {types: []jpType{jpExpref}},
  203. },
  204. handler: jpfMaxBy,
  205. hasExpRef: true,
  206. },
  207. "sum": {
  208. name: "sum",
  209. arguments: []argSpec{
  210. {types: []jpType{jpArrayNumber}},
  211. },
  212. handler: jpfSum,
  213. },
  214. "min": {
  215. name: "min",
  216. arguments: []argSpec{
  217. {types: []jpType{jpArrayNumber, jpArrayString}},
  218. },
  219. handler: jpfMin,
  220. },
  221. "min_by": {
  222. name: "min_by",
  223. arguments: []argSpec{
  224. {types: []jpType{jpArray}},
  225. {types: []jpType{jpExpref}},
  226. },
  227. handler: jpfMinBy,
  228. hasExpRef: true,
  229. },
  230. "type": {
  231. name: "type",
  232. arguments: []argSpec{
  233. {types: []jpType{jpAny}},
  234. },
  235. handler: jpfType,
  236. },
  237. "keys": {
  238. name: "keys",
  239. arguments: []argSpec{
  240. {types: []jpType{jpObject}},
  241. },
  242. handler: jpfKeys,
  243. },
  244. "values": {
  245. name: "values",
  246. arguments: []argSpec{
  247. {types: []jpType{jpObject}},
  248. },
  249. handler: jpfValues,
  250. },
  251. "sort": {
  252. name: "sort",
  253. arguments: []argSpec{
  254. {types: []jpType{jpArrayString, jpArrayNumber}},
  255. },
  256. handler: jpfSort,
  257. },
  258. "sort_by": {
  259. name: "sort_by",
  260. arguments: []argSpec{
  261. {types: []jpType{jpArray}},
  262. {types: []jpType{jpExpref}},
  263. },
  264. handler: jpfSortBy,
  265. hasExpRef: true,
  266. },
  267. "join": {
  268. name: "join",
  269. arguments: []argSpec{
  270. {types: []jpType{jpString}},
  271. {types: []jpType{jpArrayString}},
  272. },
  273. handler: jpfJoin,
  274. },
  275. "reverse": {
  276. name: "reverse",
  277. arguments: []argSpec{
  278. {types: []jpType{jpArray, jpString}},
  279. },
  280. handler: jpfReverse,
  281. },
  282. "to_array": {
  283. name: "to_array",
  284. arguments: []argSpec{
  285. {types: []jpType{jpAny}},
  286. },
  287. handler: jpfToArray,
  288. },
  289. "to_string": {
  290. name: "to_string",
  291. arguments: []argSpec{
  292. {types: []jpType{jpAny}},
  293. },
  294. handler: jpfToString,
  295. },
  296. "to_number": {
  297. name: "to_number",
  298. arguments: []argSpec{
  299. {types: []jpType{jpAny}},
  300. },
  301. handler: jpfToNumber,
  302. },
  303. "not_null": {
  304. name: "not_null",
  305. arguments: []argSpec{
  306. {types: []jpType{jpAny}, variadic: true},
  307. },
  308. handler: jpfNotNull,
  309. },
  310. }
  311. return caller
  312. }
  313. func (e *functionEntry) resolveArgs(arguments []interface{}) ([]interface{}, error) {
  314. if len(e.arguments) == 0 {
  315. return arguments, nil
  316. }
  317. if !e.arguments[len(e.arguments)-1].variadic {
  318. if len(e.arguments) != len(arguments) {
  319. return nil, errors.New("incorrect number of args")
  320. }
  321. for i, spec := range e.arguments {
  322. userArg := arguments[i]
  323. err := spec.typeCheck(userArg)
  324. if err != nil {
  325. return nil, err
  326. }
  327. }
  328. return arguments, nil
  329. }
  330. if len(arguments) < len(e.arguments) {
  331. return nil, errors.New("Invalid arity.")
  332. }
  333. return arguments, nil
  334. }
  335. func (a *argSpec) typeCheck(arg interface{}) error {
  336. for _, t := range a.types {
  337. switch t {
  338. case jpNumber:
  339. if _, ok := arg.(float64); ok {
  340. return nil
  341. }
  342. case jpString:
  343. if _, ok := arg.(string); ok {
  344. return nil
  345. }
  346. case jpArray:
  347. if isSliceType(arg) {
  348. return nil
  349. }
  350. case jpObject:
  351. if _, ok := arg.(map[string]interface{}); ok {
  352. return nil
  353. }
  354. case jpArrayNumber:
  355. if _, ok := toArrayNum(arg); ok {
  356. return nil
  357. }
  358. case jpArrayString:
  359. if _, ok := toArrayStr(arg); ok {
  360. return nil
  361. }
  362. case jpAny:
  363. return nil
  364. case jpExpref:
  365. if _, ok := arg.(expRef); ok {
  366. return nil
  367. }
  368. }
  369. }
  370. return fmt.Errorf("Invalid type for: %v, expected: %#v", arg, a.types)
  371. }
  372. func (f *functionCaller) CallFunction(name string, arguments []interface{}, intr *treeInterpreter) (interface{}, error) {
  373. entry, ok := f.functionTable[name]
  374. if !ok {
  375. return nil, errors.New("unknown function: " + name)
  376. }
  377. resolvedArgs, err := entry.resolveArgs(arguments)
  378. if err != nil {
  379. return nil, err
  380. }
  381. if entry.hasExpRef {
  382. var extra []interface{}
  383. extra = append(extra, intr)
  384. resolvedArgs = append(extra, resolvedArgs...)
  385. }
  386. return entry.handler(resolvedArgs)
  387. }
  388. func jpfAbs(arguments []interface{}) (interface{}, error) {
  389. num := arguments[0].(float64)
  390. return math.Abs(num), nil
  391. }
  392. func jpfLength(arguments []interface{}) (interface{}, error) {
  393. arg := arguments[0]
  394. if c, ok := arg.(string); ok {
  395. return float64(utf8.RuneCountInString(c)), nil
  396. } else if isSliceType(arg) {
  397. v := reflect.ValueOf(arg)
  398. return float64(v.Len()), nil
  399. } else if c, ok := arg.(map[string]interface{}); ok {
  400. return float64(len(c)), nil
  401. }
  402. return nil, errors.New("could not compute length()")
  403. }
  404. func jpfStartsWith(arguments []interface{}) (interface{}, error) {
  405. search := arguments[0].(string)
  406. prefix := arguments[1].(string)
  407. return strings.HasPrefix(search, prefix), nil
  408. }
  409. func jpfAvg(arguments []interface{}) (interface{}, error) {
  410. // We've already type checked the value so we can safely use
  411. // type assertions.
  412. args := arguments[0].([]interface{})
  413. length := float64(len(args))
  414. numerator := 0.0
  415. for _, n := range args {
  416. numerator += n.(float64)
  417. }
  418. return numerator / length, nil
  419. }
  420. func jpfCeil(arguments []interface{}) (interface{}, error) {
  421. val := arguments[0].(float64)
  422. return math.Ceil(val), nil
  423. }
  424. func jpfContains(arguments []interface{}) (interface{}, error) {
  425. search := arguments[0]
  426. el := arguments[1]
  427. if searchStr, ok := search.(string); ok {
  428. if elStr, ok := el.(string); ok {
  429. return strings.Index(searchStr, elStr) != -1, nil
  430. }
  431. return false, nil
  432. }
  433. // Otherwise this is a generic contains for []interface{}
  434. general := search.([]interface{})
  435. for _, item := range general {
  436. if item == el {
  437. return true, nil
  438. }
  439. }
  440. return false, nil
  441. }
  442. func jpfEndsWith(arguments []interface{}) (interface{}, error) {
  443. search := arguments[0].(string)
  444. suffix := arguments[1].(string)
  445. return strings.HasSuffix(search, suffix), nil
  446. }
  447. func jpfFloor(arguments []interface{}) (interface{}, error) {
  448. val := arguments[0].(float64)
  449. return math.Floor(val), nil
  450. }
  451. func jpfMap(arguments []interface{}) (interface{}, error) {
  452. intr := arguments[0].(*treeInterpreter)
  453. exp := arguments[1].(expRef)
  454. node := exp.ref
  455. arr := arguments[2].([]interface{})
  456. mapped := make([]interface{}, 0, len(arr))
  457. for _, value := range arr {
  458. current, err := intr.Execute(node, value)
  459. if err != nil {
  460. return nil, err
  461. }
  462. mapped = append(mapped, current)
  463. }
  464. return mapped, nil
  465. }
  466. func jpfMax(arguments []interface{}) (interface{}, error) {
  467. if items, ok := toArrayNum(arguments[0]); ok {
  468. if len(items) == 0 {
  469. return nil, nil
  470. }
  471. if len(items) == 1 {
  472. return items[0], nil
  473. }
  474. best := items[0]
  475. for _, item := range items[1:] {
  476. if item > best {
  477. best = item
  478. }
  479. }
  480. return best, nil
  481. }
  482. // Otherwise we're dealing with a max() of strings.
  483. items, _ := toArrayStr(arguments[0])
  484. if len(items) == 0 {
  485. return nil, nil
  486. }
  487. if len(items) == 1 {
  488. return items[0], nil
  489. }
  490. best := items[0]
  491. for _, item := range items[1:] {
  492. if item > best {
  493. best = item
  494. }
  495. }
  496. return best, nil
  497. }
  498. func jpfMerge(arguments []interface{}) (interface{}, error) {
  499. final := make(map[string]interface{})
  500. for _, m := range arguments {
  501. mapped := m.(map[string]interface{})
  502. for key, value := range mapped {
  503. final[key] = value
  504. }
  505. }
  506. return final, nil
  507. }
  508. func jpfMaxBy(arguments []interface{}) (interface{}, error) {
  509. intr := arguments[0].(*treeInterpreter)
  510. arr := arguments[1].([]interface{})
  511. exp := arguments[2].(expRef)
  512. node := exp.ref
  513. if len(arr) == 0 {
  514. return nil, nil
  515. } else if len(arr) == 1 {
  516. return arr[0], nil
  517. }
  518. start, err := intr.Execute(node, arr[0])
  519. if err != nil {
  520. return nil, err
  521. }
  522. switch t := start.(type) {
  523. case float64:
  524. bestVal := t
  525. bestItem := arr[0]
  526. for _, item := range arr[1:] {
  527. result, err := intr.Execute(node, item)
  528. if err != nil {
  529. return nil, err
  530. }
  531. current, ok := result.(float64)
  532. if !ok {
  533. return nil, errors.New("invalid type, must be number")
  534. }
  535. if current > bestVal {
  536. bestVal = current
  537. bestItem = item
  538. }
  539. }
  540. return bestItem, nil
  541. case string:
  542. bestVal := t
  543. bestItem := arr[0]
  544. for _, item := range arr[1:] {
  545. result, err := intr.Execute(node, item)
  546. if err != nil {
  547. return nil, err
  548. }
  549. current, ok := result.(string)
  550. if !ok {
  551. return nil, errors.New("invalid type, must be string")
  552. }
  553. if current > bestVal {
  554. bestVal = current
  555. bestItem = item
  556. }
  557. }
  558. return bestItem, nil
  559. default:
  560. return nil, errors.New("invalid type, must be number of string")
  561. }
  562. }
  563. func jpfSum(arguments []interface{}) (interface{}, error) {
  564. items, _ := toArrayNum(arguments[0])
  565. sum := 0.0
  566. for _, item := range items {
  567. sum += item
  568. }
  569. return sum, nil
  570. }
  571. func jpfMin(arguments []interface{}) (interface{}, error) {
  572. if items, ok := toArrayNum(arguments[0]); ok {
  573. if len(items) == 0 {
  574. return nil, nil
  575. }
  576. if len(items) == 1 {
  577. return items[0], nil
  578. }
  579. best := items[0]
  580. for _, item := range items[1:] {
  581. if item < best {
  582. best = item
  583. }
  584. }
  585. return best, nil
  586. }
  587. items, _ := toArrayStr(arguments[0])
  588. if len(items) == 0 {
  589. return nil, nil
  590. }
  591. if len(items) == 1 {
  592. return items[0], nil
  593. }
  594. best := items[0]
  595. for _, item := range items[1:] {
  596. if item < best {
  597. best = item
  598. }
  599. }
  600. return best, nil
  601. }
  602. func jpfMinBy(arguments []interface{}) (interface{}, error) {
  603. intr := arguments[0].(*treeInterpreter)
  604. arr := arguments[1].([]interface{})
  605. exp := arguments[2].(expRef)
  606. node := exp.ref
  607. if len(arr) == 0 {
  608. return nil, nil
  609. } else if len(arr) == 1 {
  610. return arr[0], nil
  611. }
  612. start, err := intr.Execute(node, arr[0])
  613. if err != nil {
  614. return nil, err
  615. }
  616. if t, ok := start.(float64); ok {
  617. bestVal := t
  618. bestItem := arr[0]
  619. for _, item := range arr[1:] {
  620. result, err := intr.Execute(node, item)
  621. if err != nil {
  622. return nil, err
  623. }
  624. current, ok := result.(float64)
  625. if !ok {
  626. return nil, errors.New("invalid type, must be number")
  627. }
  628. if current < bestVal {
  629. bestVal = current
  630. bestItem = item
  631. }
  632. }
  633. return bestItem, nil
  634. } else if t, ok := start.(string); ok {
  635. bestVal := t
  636. bestItem := arr[0]
  637. for _, item := range arr[1:] {
  638. result, err := intr.Execute(node, item)
  639. if err != nil {
  640. return nil, err
  641. }
  642. current, ok := result.(string)
  643. if !ok {
  644. return nil, errors.New("invalid type, must be string")
  645. }
  646. if current < bestVal {
  647. bestVal = current
  648. bestItem = item
  649. }
  650. }
  651. return bestItem, nil
  652. } else {
  653. return nil, errors.New("invalid type, must be number of string")
  654. }
  655. }
  656. func jpfType(arguments []interface{}) (interface{}, error) {
  657. arg := arguments[0]
  658. if _, ok := arg.(float64); ok {
  659. return "number", nil
  660. }
  661. if _, ok := arg.(string); ok {
  662. return "string", nil
  663. }
  664. if _, ok := arg.([]interface{}); ok {
  665. return "array", nil
  666. }
  667. if _, ok := arg.(map[string]interface{}); ok {
  668. return "object", nil
  669. }
  670. if arg == nil {
  671. return "null", nil
  672. }
  673. if arg == true || arg == false {
  674. return "boolean", nil
  675. }
  676. return nil, errors.New("unknown type")
  677. }
  678. func jpfKeys(arguments []interface{}) (interface{}, error) {
  679. arg := arguments[0].(map[string]interface{})
  680. collected := make([]interface{}, 0, len(arg))
  681. for key := range arg {
  682. collected = append(collected, key)
  683. }
  684. return collected, nil
  685. }
  686. func jpfValues(arguments []interface{}) (interface{}, error) {
  687. arg := arguments[0].(map[string]interface{})
  688. collected := make([]interface{}, 0, len(arg))
  689. for _, value := range arg {
  690. collected = append(collected, value)
  691. }
  692. return collected, nil
  693. }
  694. func jpfSort(arguments []interface{}) (interface{}, error) {
  695. if items, ok := toArrayNum(arguments[0]); ok {
  696. d := sort.Float64Slice(items)
  697. sort.Stable(d)
  698. final := make([]interface{}, len(d))
  699. for i, val := range d {
  700. final[i] = val
  701. }
  702. return final, nil
  703. }
  704. // Otherwise we're dealing with sort()'ing strings.
  705. items, _ := toArrayStr(arguments[0])
  706. d := sort.StringSlice(items)
  707. sort.Stable(d)
  708. final := make([]interface{}, len(d))
  709. for i, val := range d {
  710. final[i] = val
  711. }
  712. return final, nil
  713. }
  714. func jpfSortBy(arguments []interface{}) (interface{}, error) {
  715. intr := arguments[0].(*treeInterpreter)
  716. arr := arguments[1].([]interface{})
  717. exp := arguments[2].(expRef)
  718. node := exp.ref
  719. if len(arr) == 0 {
  720. return arr, nil
  721. } else if len(arr) == 1 {
  722. return arr, nil
  723. }
  724. start, err := intr.Execute(node, arr[0])
  725. if err != nil {
  726. return nil, err
  727. }
  728. if _, ok := start.(float64); ok {
  729. sortable := &byExprFloat{intr, node, arr, false}
  730. sort.Stable(sortable)
  731. if sortable.hasError {
  732. return nil, errors.New("error in sort_by comparison")
  733. }
  734. return arr, nil
  735. } else if _, ok := start.(string); ok {
  736. sortable := &byExprString{intr, node, arr, false}
  737. sort.Stable(sortable)
  738. if sortable.hasError {
  739. return nil, errors.New("error in sort_by comparison")
  740. }
  741. return arr, nil
  742. } else {
  743. return nil, errors.New("invalid type, must be number of string")
  744. }
  745. }
  746. func jpfJoin(arguments []interface{}) (interface{}, error) {
  747. sep := arguments[0].(string)
  748. // We can't just do arguments[1].([]string), we have to
  749. // manually convert each item to a string.
  750. arrayStr := []string{}
  751. for _, item := range arguments[1].([]interface{}) {
  752. arrayStr = append(arrayStr, item.(string))
  753. }
  754. return strings.Join(arrayStr, sep), nil
  755. }
  756. func jpfReverse(arguments []interface{}) (interface{}, error) {
  757. if s, ok := arguments[0].(string); ok {
  758. r := []rune(s)
  759. for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
  760. r[i], r[j] = r[j], r[i]
  761. }
  762. return string(r), nil
  763. }
  764. items := arguments[0].([]interface{})
  765. length := len(items)
  766. reversed := make([]interface{}, length)
  767. for i, item := range items {
  768. reversed[length-(i+1)] = item
  769. }
  770. return reversed, nil
  771. }
  772. func jpfToArray(arguments []interface{}) (interface{}, error) {
  773. if _, ok := arguments[0].([]interface{}); ok {
  774. return arguments[0], nil
  775. }
  776. return arguments[:1:1], nil
  777. }
  778. func jpfToString(arguments []interface{}) (interface{}, error) {
  779. if v, ok := arguments[0].(string); ok {
  780. return v, nil
  781. }
  782. result, err := json.Marshal(arguments[0])
  783. if err != nil {
  784. return nil, err
  785. }
  786. return string(result), nil
  787. }
  788. func jpfToNumber(arguments []interface{}) (interface{}, error) {
  789. arg := arguments[0]
  790. if v, ok := arg.(float64); ok {
  791. return v, nil
  792. }
  793. if v, ok := arg.(string); ok {
  794. conv, err := strconv.ParseFloat(v, 64)
  795. if err != nil {
  796. return nil, nil
  797. }
  798. return conv, nil
  799. }
  800. if _, ok := arg.([]interface{}); ok {
  801. return nil, nil
  802. }
  803. if _, ok := arg.(map[string]interface{}); ok {
  804. return nil, nil
  805. }
  806. if arg == nil {
  807. return nil, nil
  808. }
  809. if arg == true || arg == false {
  810. return nil, nil
  811. }
  812. return nil, errors.New("unknown type")
  813. }
  814. func jpfNotNull(arguments []interface{}) (interface{}, error) {
  815. for _, arg := range arguments {
  816. if arg != nil {
  817. return arg, nil
  818. }
  819. }
  820. return nil, nil
  821. }