7131dec3 by slene

add go1.2 template funcs eq, ge, gt, le, lt, ne to beego

1 parent 0ddde6fa
Showing 1 changed file with 163 additions and 3 deletions
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
9 "io/ioutil" 9 "io/ioutil"
10 "os" 10 "os"
11 "path/filepath" 11 "path/filepath"
12 "reflect"
12 "regexp" 13 "regexp"
13 "strings" 14 "strings"
14 ) 15 )
...@@ -33,13 +34,19 @@ func init() { ...@@ -33,13 +34,19 @@ func init() {
33 beegoTplFuncMap["htmlquote"] = Htmlquote 34 beegoTplFuncMap["htmlquote"] = Htmlquote
34 beegoTplFuncMap["htmlunquote"] = Htmlunquote 35 beegoTplFuncMap["htmlunquote"] = Htmlunquote
35 beegoTplFuncMap["renderform"] = RenderForm 36 beegoTplFuncMap["renderform"] = RenderForm
37
38 // go1.2 added template funcs
39 // Comparisons
40 beegoTplFuncMap["eq"] = eq // ==
41 beegoTplFuncMap["ge"] = ge // >=
42 beegoTplFuncMap["gt"] = gt // >
43 beegoTplFuncMap["le"] = le // <=
44 beegoTplFuncMap["lt"] = lt // <
45 beegoTplFuncMap["ne"] = ne // !=
36 } 46 }
37 47
38 // AddFuncMap let user to register a func in the template 48 // AddFuncMap let user to register a func in the template
39 func AddFuncMap(key string, funname interface{}) error { 49 func AddFuncMap(key string, funname interface{}) error {
40 if _, ok := beegoTplFuncMap[key]; ok {
41 return errors.New("funcmap already has the key")
42 }
43 beegoTplFuncMap[key] = funname 50 beegoTplFuncMap[key] = funname
44 return nil 51 return nil
45 } 52 }
...@@ -219,3 +226,156 @@ func _getTemplate(t0 *template.Template, root string, submods [][]string, others ...@@ -219,3 +226,156 @@ func _getTemplate(t0 *template.Template, root string, submods [][]string, others
219 } 226 }
220 return 227 return
221 } 228 }
229
230 // go1.2 added template funcs. begin
231 var (
232 errBadComparisonType = errors.New("invalid type for comparison")
233 errBadComparison = errors.New("incompatible types for comparison")
234 errNoComparison = errors.New("missing argument for comparison")
235 )
236
237 type kind int
238
239 const (
240 invalidKind kind = iota
241 boolKind
242 complexKind
243 intKind
244 floatKind
245 integerKind
246 stringKind
247 uintKind
248 )
249
250 func basicKind(v reflect.Value) (kind, error) {
251 switch v.Kind() {
252 case reflect.Bool:
253 return boolKind, nil
254 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
255 return intKind, nil
256 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
257 return uintKind, nil
258 case reflect.Float32, reflect.Float64:
259 return floatKind, nil
260 case reflect.Complex64, reflect.Complex128:
261 return complexKind, nil
262 case reflect.String:
263 return stringKind, nil
264 }
265 return invalidKind, errBadComparisonType
266 }
267
268 // eq evaluates the comparison a == b || a == c || ...
269 func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
270 v1 := reflect.ValueOf(arg1)
271 k1, err := basicKind(v1)
272 if err != nil {
273 return false, err
274 }
275 if len(arg2) == 0 {
276 return false, errNoComparison
277 }
278 for _, arg := range arg2 {
279 v2 := reflect.ValueOf(arg)
280 k2, err := basicKind(v2)
281 if err != nil {
282 return false, err
283 }
284 if k1 != k2 {
285 return false, errBadComparison
286 }
287 truth := false
288 switch k1 {
289 case boolKind:
290 truth = v1.Bool() == v2.Bool()
291 case complexKind:
292 truth = v1.Complex() == v2.Complex()
293 case floatKind:
294 truth = v1.Float() == v2.Float()
295 case intKind:
296 truth = v1.Int() == v2.Int()
297 case stringKind:
298 truth = v1.String() == v2.String()
299 case uintKind:
300 truth = v1.Uint() == v2.Uint()
301 default:
302 panic("invalid kind")
303 }
304 if truth {
305 return true, nil
306 }
307 }
308 return false, nil
309 }
310
311 // ne evaluates the comparison a != b.
312 func ne(arg1, arg2 interface{}) (bool, error) {
313 // != is the inverse of ==.
314 equal, err := eq(arg1, arg2)
315 return !equal, err
316 }
317
318 // lt evaluates the comparison a < b.
319 func lt(arg1, arg2 interface{}) (bool, error) {
320 v1 := reflect.ValueOf(arg1)
321 k1, err := basicKind(v1)
322 if err != nil {
323 return false, err
324 }
325 v2 := reflect.ValueOf(arg2)
326 k2, err := basicKind(v2)
327 if err != nil {
328 return false, err
329 }
330 if k1 != k2 {
331 return false, errBadComparison
332 }
333 truth := false
334 switch k1 {
335 case boolKind, complexKind:
336 return false, errBadComparisonType
337 case floatKind:
338 truth = v1.Float() < v2.Float()
339 case intKind:
340 truth = v1.Int() < v2.Int()
341 case stringKind:
342 truth = v1.String() < v2.String()
343 case uintKind:
344 truth = v1.Uint() < v2.Uint()
345 default:
346 panic("invalid kind")
347 }
348 return truth, nil
349 }
350
351 // le evaluates the comparison <= b.
352 func le(arg1, arg2 interface{}) (bool, error) {
353 // <= is < or ==.
354 lessThan, err := lt(arg1, arg2)
355 if lessThan || err != nil {
356 return lessThan, err
357 }
358 return eq(arg1, arg2)
359 }
360
361 // gt evaluates the comparison a > b.
362 func gt(arg1, arg2 interface{}) (bool, error) {
363 // > is the inverse of <=.
364 lessOrEqual, err := le(arg1, arg2)
365 if err != nil {
366 return false, err
367 }
368 return !lessOrEqual, nil
369 }
370
371 // ge evaluates the comparison a >= b.
372 func ge(arg1, arg2 interface{}) (bool, error) {
373 // >= is the inverse of <.
374 lessThan, err := lt(arg1, arg2)
375 if err != nil {
376 return false, err
377 }
378 return !lessThan, nil
379 }
380
381 // go1.2 added template funcs. end
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!