add go1.2 template funcs eq, ge, gt, le, lt, ne to beego
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 | ... | ... |
-
Please register or sign in to post a comment