value.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. package pongo2
  2. import (
  3. "fmt"
  4. "reflect"
  5. "sort"
  6. "strconv"
  7. "strings"
  8. )
  9. type Value struct {
  10. val reflect.Value
  11. safe bool // used to indicate whether a Value needs explicit escaping in the template
  12. }
  13. // AsValue converts any given value to a pongo2.Value
  14. // Usually being used within own functions passed to a template
  15. // through a Context or within filter functions.
  16. //
  17. // Example:
  18. // AsValue("my string")
  19. func AsValue(i interface{}) *Value {
  20. return &Value{
  21. val: reflect.ValueOf(i),
  22. }
  23. }
  24. // AsSafeValue works like AsValue, but does not apply the 'escape' filter.
  25. func AsSafeValue(i interface{}) *Value {
  26. return &Value{
  27. val: reflect.ValueOf(i),
  28. safe: true,
  29. }
  30. }
  31. func (v *Value) getResolvedValue() reflect.Value {
  32. if v.val.IsValid() && v.val.Kind() == reflect.Ptr {
  33. return v.val.Elem()
  34. }
  35. return v.val
  36. }
  37. // IsString checks whether the underlying value is a string
  38. func (v *Value) IsString() bool {
  39. return v.getResolvedValue().Kind() == reflect.String
  40. }
  41. // IsBool checks whether the underlying value is a bool
  42. func (v *Value) IsBool() bool {
  43. return v.getResolvedValue().Kind() == reflect.Bool
  44. }
  45. // IsFloat checks whether the underlying value is a float
  46. func (v *Value) IsFloat() bool {
  47. return v.getResolvedValue().Kind() == reflect.Float32 ||
  48. v.getResolvedValue().Kind() == reflect.Float64
  49. }
  50. // IsInteger checks whether the underlying value is an integer
  51. func (v *Value) IsInteger() bool {
  52. return v.getResolvedValue().Kind() == reflect.Int ||
  53. v.getResolvedValue().Kind() == reflect.Int8 ||
  54. v.getResolvedValue().Kind() == reflect.Int16 ||
  55. v.getResolvedValue().Kind() == reflect.Int32 ||
  56. v.getResolvedValue().Kind() == reflect.Int64 ||
  57. v.getResolvedValue().Kind() == reflect.Uint ||
  58. v.getResolvedValue().Kind() == reflect.Uint8 ||
  59. v.getResolvedValue().Kind() == reflect.Uint16 ||
  60. v.getResolvedValue().Kind() == reflect.Uint32 ||
  61. v.getResolvedValue().Kind() == reflect.Uint64
  62. }
  63. // IsNumber checks whether the underlying value is either an integer
  64. // or a float.
  65. func (v *Value) IsNumber() bool {
  66. return v.IsInteger() || v.IsFloat()
  67. }
  68. // IsNil checks whether the underlying value is NIL
  69. func (v *Value) IsNil() bool {
  70. //fmt.Printf("%+v\n", v.getResolvedValue().Type().String())
  71. return !v.getResolvedValue().IsValid()
  72. }
  73. // String returns a string for the underlying value. If this value is not
  74. // of type string, pongo2 tries to convert it. Currently the following
  75. // types for underlying values are supported:
  76. //
  77. // 1. string
  78. // 2. int/uint (any size)
  79. // 3. float (any precision)
  80. // 4. bool
  81. // 5. time.Time
  82. // 6. String() will be called on the underlying value if provided
  83. //
  84. // NIL values will lead to an empty string. Unsupported types are leading
  85. // to their respective type name.
  86. func (v *Value) String() string {
  87. if v.IsNil() {
  88. return ""
  89. }
  90. switch v.getResolvedValue().Kind() {
  91. case reflect.String:
  92. return v.getResolvedValue().String()
  93. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  94. return strconv.FormatInt(v.getResolvedValue().Int(), 10)
  95. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  96. return strconv.FormatUint(v.getResolvedValue().Uint(), 10)
  97. case reflect.Float32, reflect.Float64:
  98. return fmt.Sprintf("%f", v.getResolvedValue().Float())
  99. case reflect.Bool:
  100. if v.Bool() {
  101. return "True"
  102. }
  103. return "False"
  104. case reflect.Struct:
  105. if t, ok := v.Interface().(fmt.Stringer); ok {
  106. return t.String()
  107. }
  108. }
  109. logf("Value.String() not implemented for type: %s\n", v.getResolvedValue().Kind().String())
  110. return v.getResolvedValue().String()
  111. }
  112. // Integer returns the underlying value as an integer (converts the underlying
  113. // value, if necessary). If it's not possible to convert the underlying value,
  114. // it will return 0.
  115. func (v *Value) Integer() int {
  116. switch v.getResolvedValue().Kind() {
  117. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  118. return int(v.getResolvedValue().Int())
  119. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  120. return int(v.getResolvedValue().Uint())
  121. case reflect.Float32, reflect.Float64:
  122. return int(v.getResolvedValue().Float())
  123. case reflect.String:
  124. // Try to convert from string to int (base 10)
  125. f, err := strconv.ParseFloat(v.getResolvedValue().String(), 64)
  126. if err != nil {
  127. return 0
  128. }
  129. return int(f)
  130. default:
  131. logf("Value.Integer() not available for type: %s\n", v.getResolvedValue().Kind().String())
  132. return 0
  133. }
  134. }
  135. // Float returns the underlying value as a float (converts the underlying
  136. // value, if necessary). If it's not possible to convert the underlying value,
  137. // it will return 0.0.
  138. func (v *Value) Float() float64 {
  139. switch v.getResolvedValue().Kind() {
  140. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  141. return float64(v.getResolvedValue().Int())
  142. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  143. return float64(v.getResolvedValue().Uint())
  144. case reflect.Float32, reflect.Float64:
  145. return v.getResolvedValue().Float()
  146. case reflect.String:
  147. // Try to convert from string to float64 (base 10)
  148. f, err := strconv.ParseFloat(v.getResolvedValue().String(), 64)
  149. if err != nil {
  150. return 0.0
  151. }
  152. return f
  153. default:
  154. logf("Value.Float() not available for type: %s\n", v.getResolvedValue().Kind().String())
  155. return 0.0
  156. }
  157. }
  158. // Bool returns the underlying value as bool. If the value is not bool, false
  159. // will always be returned. If you're looking for true/false-evaluation of the
  160. // underlying value, have a look on the IsTrue()-function.
  161. func (v *Value) Bool() bool {
  162. switch v.getResolvedValue().Kind() {
  163. case reflect.Bool:
  164. return v.getResolvedValue().Bool()
  165. default:
  166. logf("Value.Bool() not available for type: %s\n", v.getResolvedValue().Kind().String())
  167. return false
  168. }
  169. }
  170. // IsTrue tries to evaluate the underlying value the Pythonic-way:
  171. //
  172. // Returns TRUE in one the following cases:
  173. //
  174. // * int != 0
  175. // * uint != 0
  176. // * float != 0.0
  177. // * len(array/chan/map/slice/string) > 0
  178. // * bool == true
  179. // * underlying value is a struct
  180. //
  181. // Otherwise returns always FALSE.
  182. func (v *Value) IsTrue() bool {
  183. switch v.getResolvedValue().Kind() {
  184. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  185. return v.getResolvedValue().Int() != 0
  186. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  187. return v.getResolvedValue().Uint() != 0
  188. case reflect.Float32, reflect.Float64:
  189. return v.getResolvedValue().Float() != 0
  190. case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
  191. return v.getResolvedValue().Len() > 0
  192. case reflect.Bool:
  193. return v.getResolvedValue().Bool()
  194. case reflect.Struct:
  195. return true // struct instance is always true
  196. default:
  197. logf("Value.IsTrue() not available for type: %s\n", v.getResolvedValue().Kind().String())
  198. return false
  199. }
  200. }
  201. // Negate tries to negate the underlying value. It's mainly used for
  202. // the NOT-operator and in conjunction with a call to
  203. // return_value.IsTrue() afterwards.
  204. //
  205. // Example:
  206. // AsValue(1).Negate().IsTrue() == false
  207. func (v *Value) Negate() *Value {
  208. switch v.getResolvedValue().Kind() {
  209. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
  210. reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  211. if v.Integer() != 0 {
  212. return AsValue(0)
  213. }
  214. return AsValue(1)
  215. case reflect.Float32, reflect.Float64:
  216. if v.Float() != 0.0 {
  217. return AsValue(float64(0.0))
  218. }
  219. return AsValue(float64(1.1))
  220. case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
  221. return AsValue(v.getResolvedValue().Len() == 0)
  222. case reflect.Bool:
  223. return AsValue(!v.getResolvedValue().Bool())
  224. case reflect.Struct:
  225. return AsValue(false)
  226. default:
  227. logf("Value.IsTrue() not available for type: %s\n", v.getResolvedValue().Kind().String())
  228. return AsValue(true)
  229. }
  230. }
  231. // Len returns the length for an array, chan, map, slice or string.
  232. // Otherwise it will return 0.
  233. func (v *Value) Len() int {
  234. switch v.getResolvedValue().Kind() {
  235. case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
  236. return v.getResolvedValue().Len()
  237. case reflect.String:
  238. runes := []rune(v.getResolvedValue().String())
  239. return len(runes)
  240. default:
  241. logf("Value.Len() not available for type: %s\n", v.getResolvedValue().Kind().String())
  242. return 0
  243. }
  244. }
  245. // Slice slices an array, slice or string. Otherwise it will
  246. // return an empty []int.
  247. func (v *Value) Slice(i, j int) *Value {
  248. switch v.getResolvedValue().Kind() {
  249. case reflect.Array, reflect.Slice:
  250. return AsValue(v.getResolvedValue().Slice(i, j).Interface())
  251. case reflect.String:
  252. runes := []rune(v.getResolvedValue().String())
  253. return AsValue(string(runes[i:j]))
  254. default:
  255. logf("Value.Slice() not available for type: %s\n", v.getResolvedValue().Kind().String())
  256. return AsValue([]int{})
  257. }
  258. }
  259. // Index gets the i-th item of an array, slice or string. Otherwise
  260. // it will return NIL.
  261. func (v *Value) Index(i int) *Value {
  262. switch v.getResolvedValue().Kind() {
  263. case reflect.Array, reflect.Slice:
  264. if i >= v.Len() {
  265. return AsValue(nil)
  266. }
  267. return AsValue(v.getResolvedValue().Index(i).Interface())
  268. case reflect.String:
  269. //return AsValue(v.getResolvedValue().Slice(i, i+1).Interface())
  270. s := v.getResolvedValue().String()
  271. runes := []rune(s)
  272. if i < len(runes) {
  273. return AsValue(string(runes[i]))
  274. }
  275. return AsValue("")
  276. default:
  277. logf("Value.Slice() not available for type: %s\n", v.getResolvedValue().Kind().String())
  278. return AsValue([]int{})
  279. }
  280. }
  281. // Contains checks whether the underlying value (which must be of type struct, map,
  282. // string, array or slice) contains of another Value (e. g. used to check
  283. // whether a struct contains of a specific field or a map contains a specific key).
  284. //
  285. // Example:
  286. // AsValue("Hello, World!").Contains(AsValue("World")) == true
  287. func (v *Value) Contains(other *Value) bool {
  288. switch v.getResolvedValue().Kind() {
  289. case reflect.Struct:
  290. fieldValue := v.getResolvedValue().FieldByName(other.String())
  291. return fieldValue.IsValid()
  292. case reflect.Map:
  293. var mapValue reflect.Value
  294. switch other.Interface().(type) {
  295. case int:
  296. mapValue = v.getResolvedValue().MapIndex(other.getResolvedValue())
  297. case string:
  298. mapValue = v.getResolvedValue().MapIndex(other.getResolvedValue())
  299. default:
  300. logf("Value.Contains() does not support lookup type '%s'\n", other.getResolvedValue().Kind().String())
  301. return false
  302. }
  303. return mapValue.IsValid()
  304. case reflect.String:
  305. return strings.Contains(v.getResolvedValue().String(), other.String())
  306. case reflect.Slice, reflect.Array:
  307. for i := 0; i < v.getResolvedValue().Len(); i++ {
  308. item := v.getResolvedValue().Index(i)
  309. if other.Interface() == item.Interface() {
  310. return true
  311. }
  312. }
  313. return false
  314. default:
  315. logf("Value.Contains() not available for type: %s\n", v.getResolvedValue().Kind().String())
  316. return false
  317. }
  318. }
  319. // CanSlice checks whether the underlying value is of type array, slice or string.
  320. // You normally would use CanSlice() before using the Slice() operation.
  321. func (v *Value) CanSlice() bool {
  322. switch v.getResolvedValue().Kind() {
  323. case reflect.Array, reflect.Slice, reflect.String:
  324. return true
  325. }
  326. return false
  327. }
  328. // Iterate iterates over a map, array, slice or a string. It calls the
  329. // function's first argument for every value with the following arguments:
  330. //
  331. // idx current 0-index
  332. // count total amount of items
  333. // key *Value for the key or item
  334. // value *Value (only for maps, the respective value for a specific key)
  335. //
  336. // If the underlying value has no items or is not one of the types above,
  337. // the empty function (function's second argument) will be called.
  338. func (v *Value) Iterate(fn func(idx, count int, key, value *Value) bool, empty func()) {
  339. v.IterateOrder(fn, empty, false, false)
  340. }
  341. // IterateOrder behaves like Value.Iterate, but can iterate through an array/slice/string in reverse. Does
  342. // not affect the iteration through a map because maps don't have any particular order.
  343. // However, you can force an order using the `sorted` keyword (and even use `reversed sorted`).
  344. func (v *Value) IterateOrder(fn func(idx, count int, key, value *Value) bool, empty func(), reverse bool, sorted bool) {
  345. switch v.getResolvedValue().Kind() {
  346. case reflect.Map:
  347. keys := sortedKeys(v.getResolvedValue().MapKeys())
  348. if sorted {
  349. if reverse {
  350. sort.Sort(sort.Reverse(keys))
  351. } else {
  352. sort.Sort(keys)
  353. }
  354. }
  355. keyLen := len(keys)
  356. for idx, key := range keys {
  357. value := v.getResolvedValue().MapIndex(key)
  358. if !fn(idx, keyLen, &Value{val: key}, &Value{val: value}) {
  359. return
  360. }
  361. }
  362. if keyLen == 0 {
  363. empty()
  364. }
  365. return // done
  366. case reflect.Array, reflect.Slice:
  367. var items valuesList
  368. itemCount := v.getResolvedValue().Len()
  369. for i := 0; i < itemCount; i++ {
  370. items = append(items, &Value{val: v.getResolvedValue().Index(i)})
  371. }
  372. if sorted {
  373. if reverse {
  374. sort.Sort(sort.Reverse(items))
  375. } else {
  376. sort.Sort(items)
  377. }
  378. } else {
  379. if reverse {
  380. for i := 0; i < itemCount/2; i++ {
  381. items[i], items[itemCount-1-i] = items[itemCount-1-i], items[i]
  382. }
  383. }
  384. }
  385. if len(items) > 0 {
  386. for idx, item := range items {
  387. if !fn(idx, itemCount, item, nil) {
  388. return
  389. }
  390. }
  391. } else {
  392. empty()
  393. }
  394. return // done
  395. case reflect.String:
  396. if sorted {
  397. // TODO(flosch): Handle sorted
  398. panic("TODO: handle sort for type string")
  399. }
  400. // TODO(flosch): Not utf8-compatible (utf8-decoding necessary)
  401. charCount := v.getResolvedValue().Len()
  402. if charCount > 0 {
  403. if reverse {
  404. for i := charCount - 1; i >= 0; i-- {
  405. if !fn(i, charCount, &Value{val: v.getResolvedValue().Slice(i, i+1)}, nil) {
  406. return
  407. }
  408. }
  409. } else {
  410. for i := 0; i < charCount; i++ {
  411. if !fn(i, charCount, &Value{val: v.getResolvedValue().Slice(i, i+1)}, nil) {
  412. return
  413. }
  414. }
  415. }
  416. } else {
  417. empty()
  418. }
  419. return // done
  420. default:
  421. logf("Value.Iterate() not available for type: %s\n", v.getResolvedValue().Kind().String())
  422. }
  423. empty()
  424. }
  425. // Interface gives you access to the underlying value.
  426. func (v *Value) Interface() interface{} {
  427. if v.val.IsValid() {
  428. return v.val.Interface()
  429. }
  430. return nil
  431. }
  432. // EqualValueTo checks whether two values are containing the same value or object.
  433. func (v *Value) EqualValueTo(other *Value) bool {
  434. // comparison of uint with int fails using .Interface()-comparison (see issue #64)
  435. if v.IsInteger() && other.IsInteger() {
  436. return v.Integer() == other.Integer()
  437. }
  438. return v.Interface() == other.Interface()
  439. }
  440. type sortedKeys []reflect.Value
  441. func (sk sortedKeys) Len() int {
  442. return len(sk)
  443. }
  444. func (sk sortedKeys) Less(i, j int) bool {
  445. vi := &Value{val: sk[i]}
  446. vj := &Value{val: sk[j]}
  447. switch {
  448. case vi.IsInteger() && vj.IsInteger():
  449. return vi.Integer() < vj.Integer()
  450. case vi.IsFloat() && vj.IsFloat():
  451. return vi.Float() < vj.Float()
  452. default:
  453. return vi.String() < vj.String()
  454. }
  455. }
  456. func (sk sortedKeys) Swap(i, j int) {
  457. sk[i], sk[j] = sk[j], sk[i]
  458. }
  459. type valuesList []*Value
  460. func (vl valuesList) Len() int {
  461. return len(vl)
  462. }
  463. func (vl valuesList) Less(i, j int) bool {
  464. vi := vl[i]
  465. vj := vl[j]
  466. switch {
  467. case vi.IsInteger() && vj.IsInteger():
  468. return vi.Integer() < vj.Integer()
  469. case vi.IsFloat() && vj.IsFloat():
  470. return vi.Float() < vj.Float()
  471. default:
  472. return vi.String() < vj.String()
  473. }
  474. }
  475. func (vl valuesList) Swap(i, j int) {
  476. vl[i], vl[j] = vl[j], vl[i]
  477. }