Skip to content

Commit

Permalink
add time.Time support to Value and comparison operators (#232)
Browse files Browse the repository at this point in the history
Fixes #231
  • Loading branch information
pierrre committed May 18, 2020
1 parent 76fc000 commit 1bd0148
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 0 deletions.
14 changes: 14 additions & 0 deletions parser_expression.go
Expand Up @@ -180,23 +180,37 @@ func (expr *relationalExpression) Evaluate(ctx *ExecutionContext) (*Value, *Erro
if v1.IsFloat() || v2.IsFloat() {
return AsValue(v1.Float() <= v2.Float()), nil
}
if v1.IsTime() && v2.IsTime() {
tm1, tm2 := v1.Time(), v2.Time()
return AsValue(tm1.Before(tm2) || tm1.Equal(tm2)), nil
}
return AsValue(v1.Integer() <= v2.Integer()), nil
case ">=":
if v1.IsFloat() || v2.IsFloat() {
return AsValue(v1.Float() >= v2.Float()), nil
}
if v1.IsTime() && v2.IsTime() {
tm1, tm2 := v1.Time(), v2.Time()
return AsValue(tm1.After(tm2) || tm1.Equal(tm2)), nil
}
return AsValue(v1.Integer() >= v2.Integer()), nil
case "==":
return AsValue(v1.EqualValueTo(v2)), nil
case ">":
if v1.IsFloat() || v2.IsFloat() {
return AsValue(v1.Float() > v2.Float()), nil
}
if v1.IsTime() && v2.IsTime() {
return AsValue(v1.Time().After(v2.Time())), nil
}
return AsValue(v1.Integer() > v2.Integer()), nil
case "<":
if v1.IsFloat() || v2.IsFloat() {
return AsValue(v1.Float() < v2.Float()), nil
}
if v1.IsTime() && v2.IsTime() {
return AsValue(v1.Time().Before(v2.Time())), nil
}
return AsValue(v1.Integer() < v2.Integer()), nil
case "!=", "<>":
return AsValue(!v1.EqualValueTo(v2)), nil
Expand Down
2 changes: 2 additions & 0 deletions pongo2_template_test.go
Expand Up @@ -135,6 +135,8 @@ Yep!`,
"misc_list": []interface{}{"Hello", 99, 3.14, "good"},
"escape_text": "This is \\a Test. \"Yep\". 'Yep'.",
"xss": "<script>alert(\"uh oh\");</script>",
"time1": time1,
"time2": time2,
"intmap": map[int]string{
1: "one",
5: "five",
Expand Down
7 changes: 7 additions & 0 deletions template_tests/time.tpl
@@ -0,0 +1,7 @@
{% if simple.time1 == simple.time1 %}equal{% else %}not equal{% endif %}
{% if simple.time1 > simple.time2 %}greater{% else %}not greater{% endif %}
{% if simple.time2 < simple.time1 %}lower{% else %}not lower{% endif %}
{% if simple.time1 >= simple.time2 %}greater or equal (greater){% else %}not greater or equal (greater){% endif %}
{% if simple.time1 >= simple.time1 %}greater or equal (equal){% else %}not greater or equal (equal){% endif %}
{% if simple.time2 <= simple.time1 %}lower or equal (lower){% else %}not lower or equal (lower){% endif %}
{% if simple.time2 <= simple.time2 %}lower or equal (equal){% else %}not lower or equal (equal){% endif %}
7 changes: 7 additions & 0 deletions template_tests/time.tpl.out
@@ -0,0 +1,7 @@
equal
greater
lower
greater or equal (greater)
greater or equal (equal)
lower or equal (lower)
lower or equal (equal)
20 changes: 20 additions & 0 deletions value.go
Expand Up @@ -6,6 +6,7 @@ import (
"sort"
"strconv"
"strings"
"time"
)

type Value struct {
Expand Down Expand Up @@ -76,6 +77,12 @@ func (v *Value) IsNumber() bool {
return v.IsInteger() || v.IsFloat()
}

// IsTime checks whether the underlying value is a time.Time.
func (v *Value) IsTime() bool {
_, ok := v.Interface().(time.Time)
return ok
}

// IsNil checks whether the underlying value is NIL
func (v *Value) IsNil() bool {
//fmt.Printf("%+v\n", v.getResolvedValue().Type().String())
Expand Down Expand Up @@ -185,6 +192,16 @@ func (v *Value) Bool() bool {
}
}

// Time returns the underlying value as time.Time.
// If the underlying value is not a time.Time, it returns the zero value of time.Time.
func (v *Value) Time() time.Time {
tm, ok := v.Interface().(time.Time)
if ok {
return tm
}
return time.Time{}
}

// IsTrue tries to evaluate the underlying value the Pythonic-way:
//
// Returns TRUE in one the following cases:
Expand Down Expand Up @@ -470,6 +487,9 @@ func (v *Value) EqualValueTo(other *Value) bool {
if v.IsInteger() && other.IsInteger() {
return v.Integer() == other.Integer()
}
if v.IsTime() && other.IsTime() {
return v.Time().Equal(other.Time())
}
return v.Interface() == other.Interface()
}

Expand Down

0 comments on commit 1bd0148

Please sign in to comment.