value.go 16 KB

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