1 package exec
2
3 import (
4 "fmt"
5 "reflect"
6 "sort"
7 "strconv"
8 "strings"
9
10 "github.com/pkg/errors"
11
12 log "github.com/sirupsen/logrus"
13
14 u "github.com/noirbizarre/gonja/utils"
15 )
16
17 type Value struct {
18 Val reflect.Value
19 Safe bool
20 }
21
22
23
24
25
26
27
28 func AsValue(i interface{}) *Value {
29 return &Value{
30 Val: reflect.ValueOf(i),
31 }
32 }
33
34
35 func AsSafeValue(i interface{}) *Value {
36 return &Value{
37 Val: reflect.ValueOf(i),
38 Safe: true,
39 }
40 }
41
42 func ValueError(err error) *Value {
43 return &Value{Val: reflect.ValueOf(err)}
44 }
45
46 func (v *Value) getResolvedValue() reflect.Value {
47 if v.Val.IsValid() && v.Val.Kind() == reflect.Ptr {
48 return v.Val.Elem()
49 }
50 return v.Val
51 }
52
53
54 func (v *Value) IsString() bool {
55 return v.getResolvedValue().Kind() == reflect.String
56 }
57
58
59 func (v *Value) IsBool() bool {
60 return v.getResolvedValue().Kind() == reflect.Bool
61 }
62
63
64 func (v *Value) IsFloat() bool {
65 return v.getResolvedValue().Kind() == reflect.Float32 ||
66 v.getResolvedValue().Kind() == reflect.Float64
67 }
68
69
70 func (v *Value) IsInteger() bool {
71 kind := v.getResolvedValue().Kind()
72 return kind == reflect.Int || kind == reflect.Int8 || kind == reflect.Int16 ||
73 kind == reflect.Int32 || kind == reflect.Int64 || kind == reflect.Uint ||
74 kind == reflect.Uint8 || kind == reflect.Uint16 || kind == reflect.Uint32 ||
75 kind == reflect.Uint64
76 }
77
78
79
80 func (v *Value) IsNumber() bool {
81 return v.IsInteger() || v.IsFloat()
82 }
83
84 func (v *Value) IsCallable() bool {
85 return v.getResolvedValue().Kind() == reflect.Func
86 }
87
88 func (v *Value) IsList() bool {
89 kind := v.getResolvedValue().Kind()
90 return kind == reflect.Array || kind == reflect.Slice
91 }
92
93 func (v *Value) IsDict() bool {
94 resolved := v.getResolvedValue()
95 return resolved.Kind() == reflect.Map || resolved.Kind() == reflect.Struct && resolved.Type() == TypeDict
96 }
97
98 func (v *Value) IsIterable() bool {
99 return v.IsString() || v.IsList() || v.IsDict()
100 }
101
102
103 func (v *Value) IsNil() bool {
104 return !v.getResolvedValue().IsValid()
105 }
106
107 func (v *Value) IsError() bool {
108 if v.IsNil() || !v.getResolvedValue().CanInterface() {
109 return false
110 }
111 _, ok := v.Interface().(error)
112 return ok
113 }
114
115 func (v *Value) Error() string {
116 if v.IsError() {
117 return v.Interface().(error).Error()
118 }
119 return ""
120 }
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 func (v *Value) String() string {
136 if v.IsNil() {
137 return ""
138 }
139 resolved := v.getResolvedValue()
140
141 switch resolved.Kind() {
142 case reflect.String:
143 return resolved.String()
144 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
145 return strconv.FormatInt(resolved.Int(), 10)
146 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
147 return strconv.FormatUint(resolved.Uint(), 10)
148 case reflect.Float32, reflect.Float64:
149 formated := strconv.FormatFloat(resolved.Float(), 'f', 11, 64)
150 if !strings.Contains(formated, ".") {
151 formated = formated + "."
152 }
153 formated = strings.TrimRight(formated, "0")
154 if formated[len(formated)-1] == '.' {
155 formated += "0"
156 }
157 return formated
158 case reflect.Bool:
159 if v.Bool() {
160 return "True"
161 }
162 return "False"
163 case reflect.Struct:
164 if t, ok := v.Interface().(fmt.Stringer); ok {
165 return t.String()
166 }
167 case reflect.Slice, reflect.Array:
168 var out strings.Builder
169 length := v.Len()
170 out.WriteByte('[')
171 for i := 0; i < length; i++ {
172 if i > 0 {
173 out.WriteString(", ")
174 }
175 item := ToValue(v.Index(i).Val)
176 if item.IsString() {
177 out.WriteString(fmt.Sprintf(`'%s'`, item.String()))
178 } else {
179 out.WriteString(item.String())
180 }
181 }
182 out.WriteByte(']')
183 return out.String()
184 case reflect.Map:
185 pairs := []string{}
186 for _, key := range resolved.MapKeys() {
187 keyLabel := key.String()
188 if key.Kind() == reflect.String {
189 keyLabel = fmt.Sprintf(`'%s'`, keyLabel)
190 }
191
192 value := resolved.MapIndex(key)
193
194 for value.Kind() == reflect.Interface {
195 value = reflect.ValueOf(value.Interface())
196 }
197 valueLabel := value.String()
198 if value.Kind() == reflect.String {
199 valueLabel = fmt.Sprintf(`'%s'`, valueLabel)
200 }
201 pair := fmt.Sprintf(`%s: %s`, keyLabel, valueLabel)
202 pairs = append(pairs, pair)
203 }
204 sort.Strings(pairs)
205 return fmt.Sprintf("{%s}", strings.Join(pairs, ", "))
206 }
207
208 log.Errorf("Value.String() not implemented for type: %s\n", resolved.Kind().String())
209 return resolved.String()
210 }
211
212
213 func (v *Value) Escaped() string {
214 return u.Escape(v.String())
215 }
216
217
218
219
220 func (v *Value) Integer() int {
221 switch v.getResolvedValue().Kind() {
222 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
223 return int(v.getResolvedValue().Int())
224 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
225 return int(v.getResolvedValue().Uint())
226 case reflect.Float32, reflect.Float64:
227 return int(v.getResolvedValue().Float())
228 case reflect.String:
229
230 f, err := strconv.ParseFloat(v.getResolvedValue().String(), 64)
231 if err != nil {
232 return 0
233 }
234 return int(f)
235 default:
236 log.Errorf("Value.Integer() not available for type: %s\n", v.getResolvedValue().Kind().String())
237 return 0
238 }
239 }
240
241
242
243
244 func (v *Value) Float() float64 {
245 switch v.getResolvedValue().Kind() {
246 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
247 return float64(v.getResolvedValue().Int())
248 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
249 return float64(v.getResolvedValue().Uint())
250 case reflect.Float32, reflect.Float64:
251 return v.getResolvedValue().Float()
252 case reflect.String:
253
254 f, err := strconv.ParseFloat(v.getResolvedValue().String(), 64)
255 if err != nil {
256 return 0.0
257 }
258 return f
259 default:
260 log.Errorf("Value.Float() not available for type: %s\n", v.getResolvedValue().Kind().String())
261 return 0.0
262 }
263 }
264
265
266
267
268 func (v *Value) Bool() bool {
269 switch v.getResolvedValue().Kind() {
270 case reflect.Bool:
271 return v.getResolvedValue().Bool()
272 default:
273 log.Errorf("Value.Bool() not available for type: %s\n", v.getResolvedValue().Kind().String())
274 return false
275 }
276 }
277
278
279
280
281
282
283
284
285
286
287
288
289
290 func (v *Value) IsTrue() bool {
291 if v.IsNil() || v.IsError() {
292 return false
293 }
294 switch v.getResolvedValue().Kind() {
295 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
296 return v.getResolvedValue().Int() != 0
297 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
298 return v.getResolvedValue().Uint() != 0
299 case reflect.Float32, reflect.Float64:
300 return v.getResolvedValue().Float() != 0
301 case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
302 return v.getResolvedValue().Len() > 0
303 case reflect.Bool:
304 return v.getResolvedValue().Bool()
305 case reflect.Struct:
306 return true
307 default:
308 log.Errorf("Value.IsTrue() not available for type: %s\n", v.getResolvedValue().Kind().String())
309 return false
310 }
311 }
312
313
314
315
316
317
318
319 func (v *Value) Negate() *Value {
320 switch v.getResolvedValue().Kind() {
321 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
322 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
323 if v.Integer() != 0 {
324 return AsValue(0)
325 }
326 return AsValue(1)
327 case reflect.Float32, reflect.Float64:
328 if v.Float() != 0.0 {
329 return AsValue(float64(0.0))
330 }
331 return AsValue(float64(1.1))
332 case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
333 return AsValue(v.getResolvedValue().Len() == 0)
334 case reflect.Bool:
335 return AsValue(!v.getResolvedValue().Bool())
336 case reflect.Struct:
337 return AsValue(false)
338 default:
339 log.Errorf("Value.IsTrue() not available for type: %s\n", v.getResolvedValue().Kind().String())
340 return AsValue(true)
341 }
342 }
343
344
345
346 func (v *Value) Len() int {
347 switch v.getResolvedValue().Kind() {
348 case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
349 return v.getResolvedValue().Len()
350 case reflect.String:
351 runes := []rune(v.getResolvedValue().String())
352 return len(runes)
353 default:
354 log.Errorf("Value.Len() not available for type: %s\n", v.getResolvedValue().Kind().String())
355 return 0
356 }
357 }
358
359
360
361 func (v *Value) Slice(i, j int) *Value {
362 switch v.getResolvedValue().Kind() {
363 case reflect.Array, reflect.Slice:
364 return AsValue(v.getResolvedValue().Slice(i, j).Interface())
365 case reflect.String:
366 runes := []rune(v.getResolvedValue().String())
367 return AsValue(string(runes[i:j]))
368 default:
369 log.Errorf("Value.Slice() not available for type: %s\n", v.getResolvedValue().Kind().String())
370 return AsValue([]int{})
371 }
372 }
373
374
375
376 func (v *Value) Index(i int) *Value {
377 switch v.getResolvedValue().Kind() {
378 case reflect.Array, reflect.Slice:
379 if i >= v.Len() {
380 return AsValue(nil)
381 }
382 return AsValue(v.getResolvedValue().Index(i).Interface())
383 case reflect.String:
384
385 s := v.getResolvedValue().String()
386 runes := []rune(s)
387 if i < len(runes) {
388 return AsValue(string(runes[i]))
389 }
390 return AsValue("")
391 default:
392 log.Errorf("Value.Slice() not available for type: %s\n", v.getResolvedValue().Kind().String())
393 return AsValue([]int{})
394 }
395 }
396
397
398
399
400
401
402
403 func (v *Value) Contains(other *Value) bool {
404 resolved := v.getResolvedValue()
405 switch resolved.Kind() {
406 case reflect.Struct:
407 if dict, ok := resolved.Interface().(Dict); ok {
408 return dict.Keys().Contains(other)
409 }
410 fieldValue := resolved.FieldByName(other.String())
411 return fieldValue.IsValid()
412 case reflect.Map:
413 var mapValue reflect.Value
414 switch other.Interface().(type) {
415 case int:
416 mapValue = resolved.MapIndex(other.getResolvedValue())
417 case string:
418 mapValue = resolved.MapIndex(other.getResolvedValue())
419 default:
420 log.Errorf("Value.Contains() does not support lookup type '%s'\n", other.getResolvedValue().Kind().String())
421 return false
422 }
423
424 return mapValue.IsValid()
425 case reflect.String:
426 return strings.Contains(resolved.String(), other.String())
427
428 case reflect.Slice, reflect.Array:
429 if vl, ok := resolved.Interface().(ValuesList); ok {
430 return vl.Contains(other)
431 }
432 for i := 0; i < resolved.Len(); i++ {
433 item := resolved.Index(i)
434 if other.Interface() == item.Interface() {
435 return true
436 }
437 }
438 return false
439
440 default:
441 fmt.Println("default")
442 log.Errorf("Value.Contains() not available for type: %s\n", resolved.Kind().String())
443 return false
444 }
445 }
446
447
448
449 func (v *Value) CanSlice() bool {
450 switch v.getResolvedValue().Kind() {
451 case reflect.Array, reflect.Slice, reflect.String:
452 return true
453 }
454 return false
455 }
456
457
458
459
460
461
462
463
464
465
466
467 func (v *Value) Iterate(fn func(idx, count int, key, value *Value) bool, empty func()) {
468 v.IterateOrder(fn, empty, false, false, false)
469 }
470
471
472
473
474 func (v *Value) IterateOrder(fn func(idx, count int, key, value *Value) bool, empty func(), reverse bool, sorted bool, caseSensitive bool) {
475 resolved := v.getResolvedValue()
476 switch resolved.Kind() {
477 case reflect.Map:
478 keys := v.Keys()
479 if sorted {
480 if reverse {
481 if !caseSensitive {
482 sort.Sort(sort.Reverse(CaseInsensitive(keys)))
483 } else {
484 sort.Sort(sort.Reverse(keys))
485 }
486 } else {
487 if !caseSensitive {
488 sort.Sort(CaseInsensitive(keys))
489 } else {
490 sort.Sort(keys)
491 }
492 }
493 }
494 keyLen := len(keys)
495 for idx, key := range keys {
496 value, _ := v.Getitem(key.Interface())
497 if !fn(idx, keyLen, key, value) {
498 return
499 }
500 }
501 if keyLen == 0 {
502 empty()
503 }
504 return
505 case reflect.Array, reflect.Slice:
506 var items ValuesList
507
508 itemCount := resolved.Len()
509 for i := 0; i < itemCount; i++ {
510
511
512 items = append(items, ToValue(resolved.Index(i)))
513 }
514
515 if sorted {
516 if reverse {
517 if !caseSensitive && items[0].IsString() {
518 sort.Slice(items, func(i, j int) bool {
519 return strings.ToLower(items[i].String()) > strings.ToLower(items[j].String())
520 })
521 } else {
522 sort.Sort(sort.Reverse(items))
523 }
524 } else {
525 if !caseSensitive && items[0].IsString() {
526 sort.Slice(items, func(i, j int) bool {
527 return strings.ToLower(items[i].String()) < strings.ToLower(items[j].String())
528 })
529 } else {
530 sort.Sort(items)
531 }
532 }
533 } else {
534 if reverse {
535 for i := 0; i < itemCount/2; i++ {
536 items[i], items[itemCount-1-i] = items[itemCount-1-i], items[i]
537 }
538 }
539 }
540
541 if len(items) > 0 {
542 for idx, item := range items {
543 if !fn(idx, itemCount, item, nil) {
544 return
545 }
546 }
547 } else {
548 empty()
549 }
550 return
551 case reflect.String:
552 if sorted {
553 r := []rune(resolved.String())
554 if caseSensitive {
555 sort.Sort(sortRunes(r))
556 } else {
557 sort.Sort(CaseInsensitive(sortRunes(r)))
558 }
559 resolved = reflect.ValueOf(string(r))
560 }
561
562
563 charCount := resolved.Len()
564 if charCount > 0 {
565 if reverse {
566 for i := charCount - 1; i >= 0; i-- {
567 if !fn(i, charCount, &Value{Val: resolved.Slice(i, i+1)}, nil) {
568 return
569 }
570 }
571 } else {
572 for i := 0; i < charCount; i++ {
573 if !fn(i, charCount, &Value{Val: resolved.Slice(i, i+1)}, nil) {
574 return
575 }
576 }
577 }
578 } else {
579 empty()
580 }
581 return
582 case reflect.Chan:
583 items := []reflect.Value{}
584 for {
585 value, ok := resolved.Recv()
586 if !ok {
587 break
588 }
589 items = append(items, value)
590 }
591 count := len(items)
592 if count > 0 {
593 for idx, value := range items {
594 fn(idx, count, &Value{Val: value}, nil)
595 }
596 } else {
597 empty()
598 }
599 return
600 case reflect.Struct:
601 if resolved.Type() != TypeDict {
602 log.Errorf("Value.Iterate() not available for type: %s\n", resolved.Kind().String())
603 }
604 dict := resolved.Interface().(Dict)
605 keys := dict.Keys()
606 length := len(dict.Pairs)
607 if sorted {
608 if reverse {
609 if !caseSensitive {
610 sort.Sort(sort.Reverse(CaseInsensitive(keys)))
611 } else {
612 sort.Sort(sort.Reverse(keys))
613 }
614 } else {
615 if !caseSensitive {
616 sort.Sort(CaseInsensitive(keys))
617 } else {
618 sort.Sort(keys)
619 }
620 }
621 }
622 if len(keys) > 0 {
623 for idx, key := range keys {
624 if !fn(idx, length, key, dict.Get(key)) {
625 return
626 }
627 }
628 } else {
629 empty()
630 }
631
632 default:
633 log.Errorf("Value.Iterate() not available for type: %s\n", resolved.Kind().String())
634 }
635 empty()
636 }
637
638
639 func (v *Value) Interface() interface{} {
640 if v.Val.IsValid() {
641 return v.Val.Interface()
642 }
643 return nil
644 }
645
646
647 func (v *Value) EqualValueTo(other *Value) bool {
648
649 if v.IsInteger() && other.IsInteger() {
650 return v.Integer() == other.Integer()
651 }
652 return v.Interface() == other.Interface()
653 }
654
655 func (v *Value) Keys() ValuesList {
656 keys := ValuesList{}
657 if v.IsNil() {
658 return keys
659 }
660 resolved := v.getResolvedValue()
661 if resolved.Type() == TypeDict {
662 for _, pair := range resolved.Interface().(Dict).Pairs {
663 keys = append(keys, pair.Key)
664 }
665 return keys
666 } else if resolved.Kind() != reflect.Map {
667 return keys
668 }
669 for _, key := range resolved.MapKeys() {
670 keys = append(keys, &Value{Val: key})
671 }
672 sort.Sort(CaseInsensitive(keys))
673 return keys
674 }
675
676 func (v *Value) Items() []*Pair {
677 out := []*Pair{}
678 resolved := v.getResolvedValue()
679 if resolved.Kind() != reflect.Map {
680 return out
681 }
682 iter := resolved.MapRange()
683 for iter.Next() {
684 out = append(out, &Pair{
685 Key: &Value{Val: iter.Key()},
686 Value: &Value{Val: iter.Value()},
687 })
688 }
689 return out
690 }
691
692 func ToValue(data interface{}) *Value {
693 var isSafe bool
694
695
696
697 value, ok := data.(*Value)
698 if ok {
699 return value
700 }
701
702 val, ok := data.(reflect.Value)
703 if !ok {
704 val = reflect.ValueOf(data)
705 }
706
707 if !val.IsValid() {
708
709 return AsValue(nil)
710 }
711
712 if val.Type() == reflect.TypeOf(reflect.Value{}) {
713 val = val.Interface().(reflect.Value)
714 } else if val.Type() == reflect.TypeOf(&reflect.Value{}) {
715 val = *(val.Interface().(*reflect.Value))
716 }
717
718 if !val.IsValid() {
719
720 return AsValue(nil)
721 }
722
723
724 for val.Kind() == reflect.Interface {
725 val = reflect.ValueOf(val.Interface())
726 }
727
728 if !val.IsValid() {
729
730 return AsValue(nil)
731 }
732
733
734
735
736 if val.Type() == typeOfValuePtr {
737 tmpValue := val.Interface().(*Value)
738 val = tmpValue.Val
739 isSafe = tmpValue.Safe
740 }
741
742 if !val.IsValid() {
743
744 return AsValue(nil)
745 }
746 return &Value{Val: val, Safe: isSafe}
747 }
748
749 func (v *Value) Getattr(name string) (*Value, bool) {
750 if v.IsNil() {
751 return AsValue(errors.New(`Can't use getattr on None`)), false
752 }
753 var val reflect.Value
754 val = v.Val.MethodByName(name)
755 if val.IsValid() {
756 return ToValue(val), true
757 }
758 if v.Val.Kind() == reflect.Ptr {
759 val = v.Val.Elem()
760 if !val.IsValid() {
761
762 return AsValue(nil), false
763 }
764 } else {
765 val = v.Val
766 }
767
768 if val.Kind() == reflect.Struct {
769 field := val.FieldByName(name)
770 if field.IsValid() {
771 return ToValue(field), true
772 }
773 }
774
775 return AsValue(nil), false
776 }
777
778 func (v *Value) Getitem(key interface{}) (*Value, bool) {
779 if v.IsNil() {
780 return AsValue(errors.New(`Can't use Getitem on None`)), false
781 }
782 var val reflect.Value
783 if v.Val.Kind() == reflect.Ptr {
784 val = v.Val.Elem()
785 if !val.IsValid() {
786
787 return AsValue(nil), false
788 }
789 } else {
790 val = v.Val
791 }
792
793 switch t := key.(type) {
794 case string:
795 if val.Kind() == reflect.Map {
796 atKey := val.MapIndex(reflect.ValueOf(t))
797 if atKey.IsValid() {
798 return ToValue(atKey), true
799 }
800 } else if val.Kind() == reflect.Struct && val.Type() == TypeDict {
801 for _, pair := range val.Interface().(Dict).Pairs {
802 if pair.Key.String() == t {
803 return pair.Value, true
804 }
805 }
806 }
807
808 case int:
809 switch val.Kind() {
810 case reflect.String, reflect.Array, reflect.Slice:
811 if t >= 0 && val.Len() > t {
812 atIndex := val.Index(t)
813 if atIndex.IsValid() {
814 return ToValue(atIndex), true
815 }
816 } else {
817
818 return AsValue(nil), false
819 }
820 default:
821 return AsValue(errors.Errorf("Can't access an index on type %s (variable %s)", val.Kind().String(), v)), false
822 }
823 default:
824 return AsValue(nil), false
825 }
826
827 return AsValue(nil), false
828 }
829
830 func (v *Value) Get(key string) (*Value, bool) {
831 value, found := v.Getattr(key)
832 if !found {
833 value, found = v.Getitem(key)
834 }
835 return value, found
836 }
837
838 func (v *Value) Set(key string, value interface{}) error {
839 if v.IsNil() {
840 return errors.New(`Can't set attribute or item on None`)
841 }
842 val := v.Val
843 for val.Kind() == reflect.Ptr {
844 val = val.Elem()
845 if !val.IsValid() {
846
847 return errors.Errorf(`Invalid value "%s"`, val)
848 }
849 }
850
851 switch val.Kind() {
852 case reflect.Struct:
853 field := val.FieldByName(key)
854 if field.IsValid() && field.CanSet() {
855 field.Set(reflect.ValueOf(value))
856 } else {
857 return errors.Errorf(`Can't write field "%s"`, key)
858 }
859 case reflect.Map:
860 val.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(value))
861 default:
862 return errors.Errorf(`Unkown type "%s", can't set value on "%s"`, val.Kind(), key)
863 }
864
865 return nil
866 }
867
868 type ValuesList []*Value
869
870 func (vl ValuesList) Len() int {
871 return len(vl)
872 }
873
874 func (vl ValuesList) Less(i, j int) bool {
875 vi := vl[i]
876 vj := vl[j]
877 switch {
878 case vi.IsInteger() && vj.IsInteger():
879 return vi.Integer() < vj.Integer()
880 case vi.IsFloat() && vj.IsFloat():
881 return vi.Float() < vj.Float()
882 default:
883 return vi.String() < vj.String()
884 }
885 }
886
887 func (vl ValuesList) Swap(i, j int) {
888 vl[i], vl[j] = vl[j], vl[i]
889 }
890
891 func (vl ValuesList) String() string {
892 var out strings.Builder
893 out.WriteByte('[')
894 for idx, key := range vl {
895 if idx > 0 {
896 out.WriteString(", ")
897 }
898 if key.IsString() {
899 out.WriteString("'")
900 }
901 out.WriteString(key.String())
902 if key.IsString() {
903 out.WriteString("'")
904 }
905 }
906 out.WriteByte(']')
907 return out.String()
908 }
909
910 func (vl ValuesList) Contains(value *Value) bool {
911 for _, val := range vl {
912 if value.EqualValueTo(val) {
913 return true
914 }
915 }
916 return false
917 }
918
919 type Pair struct {
920 Key *Value
921 Value *Value
922 }
923
924 func (p *Pair) String() string {
925 var key, value string
926 if p.Key.IsString() {
927 key = fmt.Sprintf(`'%s'`, p.Key.String())
928 } else {
929 key = p.Key.String()
930 }
931 if p.Value.IsString() {
932 value = fmt.Sprintf(`'%s'`, p.Value.String())
933 } else {
934 value = p.Value.String()
935 }
936 return fmt.Sprintf(`%s: %s`, key, value)
937 }
938
939 type Dict struct {
940 Pairs []*Pair
941 }
942
943 func NewDict() *Dict {
944 return &Dict{Pairs: []*Pair{}}
945 }
946
947 func (d *Dict) String() string {
948 pairs := []string{}
949 for _, pair := range d.Pairs {
950 pairs = append(pairs, pair.String())
951 }
952 return fmt.Sprintf(`{%s}`, strings.Join(pairs, ", "))
953 }
954
955 func (d *Dict) Keys() ValuesList {
956 keys := ValuesList{}
957 for _, pair := range d.Pairs {
958 keys = append(keys, pair.Key)
959 }
960 return keys
961 }
962
963 func (d *Dict) Get(key *Value) *Value {
964 for _, pair := range d.Pairs {
965 if pair.Key.EqualValueTo(key) {
966 return pair.Value
967 }
968 }
969 return AsValue(nil)
970 }
971
972 var TypeDict = reflect.TypeOf(Dict{})
973
974 type sortRunes []rune
975
976 func (s sortRunes) Less(i, j int) bool {
977 return s[i] < s[j]
978 }
979
980 func (s sortRunes) Swap(i, j int) {
981 s[i], s[j] = s[j], s[i]
982 }
983
984 func (s sortRunes) Len() int {
985 return len(s)
986 }
987
988 type caseInsensitiveSortedRunes struct {
989 sortRunes
990 }
991
992 func (ci caseInsensitiveSortedRunes) Less(i, j int) bool {
993 return strings.ToLower(string(ci.sortRunes[i])) < strings.ToLower(string(ci.sortRunes[j]))
994 }
995
996 type caseInsensitiveValueList struct {
997 ValuesList
998 }
999
1000 func (ci caseInsensitiveValueList) Less(i, j int) bool {
1001 vi := ci.ValuesList[i]
1002 vj := ci.ValuesList[j]
1003 switch {
1004 case vi.IsInteger() && vj.IsInteger():
1005 return vi.Integer() < vj.Integer()
1006 case vi.IsFloat() && vj.IsFloat():
1007 return vi.Float() < vj.Float()
1008 default:
1009 return strings.ToLower(vi.String()) < strings.ToLower(vj.String())
1010 }
1011 }
1012
1013
1014 func CaseInsensitive(data sort.Interface) sort.Interface {
1015 if vl, ok := data.(ValuesList); ok {
1016 return &caseInsensitiveValueList{vl}
1017 } else if sr, ok := data.(sortRunes); ok {
1018 return &caseInsensitiveSortedRunes{sr}
1019 }
1020 return data
1021 }
1022
View as plain text