github.com/yaoapp/kun@v0.9.0/any/any.go (about) 1 package any 2 3 import ( 4 "database/sql/driver" 5 "encoding/json" 6 "fmt" 7 "reflect" 8 "regexp" 9 "strconv" 10 "strings" 11 "time" 12 13 "github.com/yaoapp/kun/day" 14 "github.com/yaoapp/kun/maps" 15 "github.com/yaoapp/kun/num" 16 ) 17 18 // Any the replacement for interface{} 19 type Any struct { 20 value interface{} 21 } 22 23 var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)") 24 var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])") 25 26 // Make create a empty instance 27 func Make() *Any { 28 return &Any{value: nil} 29 } 30 31 // Of create a new instance 32 func Of(value interface{}) *Any { 33 return &Any{value: value} 34 } 35 36 // Set set <value> to <v>, and returns the old value. 37 func (v *Any) Set(value interface{}) (old interface{}) { 38 old = v.value 39 v.value = value 40 return old 41 } 42 43 // Get returns the current value of <v>. 44 func (v Any) Get() interface{} { 45 return v.value 46 } 47 48 // Val is alias of Get. 49 func (v Any) Val() interface{} { 50 return v.Get() 51 } 52 53 // Interface is alias of Get. 54 func (v Any) Interface() interface{} { 55 return v.Get() 56 } 57 58 // Interfaces converts and returns <v> as []interfaces{}. 59 func (v Any) Interfaces() []interface{} { 60 if v.value == nil { 61 return []interface{}{} 62 } 63 values := reflect.ValueOf(v.value) 64 values = reflect.Indirect(values) 65 kind := values.Kind() 66 if kind != reflect.Array && kind != reflect.Slice { 67 return []interface{}{v.value} 68 } 69 res := []interface{}{} 70 for i := 0; i < values.Len(); i++ { 71 v := values.Index(i).Interface() 72 res = append(res, v) 73 } 74 return res 75 } 76 77 // String returns <v> as string. 78 func (v Any) String() string { 79 if v.value == nil { 80 return "" 81 } 82 value, ok := v.value.(string) 83 if !ok { 84 panic("v is not a type of string") 85 } 86 return value 87 } 88 89 // CString converts and returns <v> as string. 90 func (v Any) CString() string { 91 if v.value == nil { 92 return "" 93 } 94 95 value, ok := v.value.(string) 96 if ok { 97 return value 98 } 99 return fmt.Sprintf("%v", v.value) 100 } 101 102 // Strings returns <v> as []string. 103 func (v Any) Strings() []string { 104 if v.value == nil { 105 return []string{} 106 } 107 value, ok := v.value.([]string) 108 if !ok { 109 panic("v is not a type of []string") 110 } 111 return value 112 } 113 114 // CStrings converts and returns <v> as []string. 115 func (v Any) CStrings() []string { 116 if v.value == nil { 117 return []string{} 118 } 119 120 values := reflect.ValueOf(v.value) 121 values = reflect.Indirect(values) 122 kind := values.Kind() 123 if kind != reflect.Array && kind != reflect.Slice { 124 return []string{Of(v.value).CString()} 125 } 126 res := []string{} 127 for i := 0; i < values.Len(); i++ { 128 v := values.Index(i).Interface() 129 res = append(res, Of(v).CString()) 130 } 131 return res 132 } 133 134 // Array returns <v> as []interface{} 135 func (v Any) Array() []interface{} { 136 if v.value == nil { 137 return []interface{}{} 138 } 139 140 value, ok := v.value.([]interface{}) 141 if !ok { 142 panic("v is not a type of []interface{}") 143 } 144 return value 145 } 146 147 // CArray returns <v> as []interface{} 148 func (v Any) CArray() []interface{} { 149 if v.value == nil { 150 return []interface{}{} 151 } 152 153 if !v.IsArray() && !v.IsSlice() { 154 panic("v is not a type of Array of Slice") 155 } 156 157 res := []interface{}{} 158 values := reflect.ValueOf(v.value) 159 values = reflect.Indirect(values) 160 for i := 0; i < values.Len(); i++ { 161 res = append(res, values.Index(i).Interface()) 162 } 163 return res 164 } 165 166 // Int returns <v> as int 167 func (v Any) Int() int { 168 if v.value == nil { 169 return 0 170 } 171 172 value, ok := v.value.(int) 173 if !ok { 174 panic("v is not a type of int") 175 } 176 return value 177 } 178 179 // CInt converts and returns <v> as int 180 func (v Any) CInt() int { 181 182 if v.value == nil { 183 return 0 184 } 185 186 value, ok := v.value.(int) 187 if ok { 188 return value 189 } 190 191 value, _ = strconv.Atoi(fmt.Sprintf("%.0f", v.CFloat64())) 192 // if err != nil { 193 // panic(err.Error()) 194 // } 195 return value 196 } 197 198 // Ints returns <v> as []int 199 func (v Any) Ints() []int { 200 if v.value == nil { 201 return []int{} 202 } 203 value, ok := v.value.([]int) 204 if !ok { 205 panic("v is not a type of []int") 206 } 207 return value 208 } 209 210 // CInts converts and returns <v> as []int 211 func (v Any) CInts() []int { 212 213 if v.value == nil { 214 return []int{} 215 } 216 217 values := reflect.ValueOf(v.value) 218 values = reflect.Indirect(values) 219 kind := values.Kind() 220 if kind != reflect.Array && kind != reflect.Slice { 221 return []int{Of(v.value).CInt()} 222 } 223 res := []int{} 224 for i := 0; i < values.Len(); i++ { 225 v := values.Index(i).Interface() 226 res = append(res, Of(v).CInt()) 227 } 228 return res 229 } 230 231 // Float is alias of Float64 returns <v> as float64 232 func (v Any) Float() float64 { 233 return v.Float64() 234 } 235 236 // Float64 returns <v> as float64 237 func (v Any) Float64() float64 { 238 if v.value == nil { 239 return 0 240 } 241 242 value, ok := v.value.(float64) 243 if !ok { 244 panic("v is not a type of float64") 245 } 246 return value 247 } 248 249 // CFloat is alias of CFloat64 converts and returns <v> as float64 250 func (v Any) CFloat() float64 { 251 return v.CFloat64() 252 } 253 254 // CFloat64 converts and returns <v> as float64 255 func (v Any) CFloat64() float64 { 256 257 if v.value == nil { 258 return 0 259 } 260 261 value, ok := v.value.(float64) 262 if ok { 263 return value 264 } 265 266 if v.IsString() && v.String() == "" { 267 return 0 268 } 269 270 value, err := strconv.ParseFloat(fmt.Sprintf("%v", v.value), 64) 271 if err != nil { 272 panic(err.Error()) 273 } 274 return value 275 } 276 277 // Floats is alias of Float64s returns <v> as []float64 278 func (v Any) Floats() []float64 { 279 return v.Float64s() 280 } 281 282 // Float64s returns <v> as []float64 283 func (v Any) Float64s() []float64 { 284 if v.value == nil { 285 return []float64{} 286 } 287 value, ok := v.value.([]float64) 288 if !ok { 289 panic("v is not a type of []float64") 290 } 291 return value 292 } 293 294 // CFloats is alias of CFloat64s converts and returns <v> as []float64 295 func (v Any) CFloats() []float64 { 296 return v.CFloat64s() 297 } 298 299 // CFloat64s converts and returns <v> as []float64 300 func (v Any) CFloat64s() []float64 { 301 302 if v.value == nil { 303 return []float64{} 304 } 305 306 values := reflect.ValueOf(v.value) 307 values = reflect.Indirect(values) 308 kind := values.Kind() 309 if kind != reflect.Array && kind != reflect.Slice { 310 return []float64{Of(v.value).CFloat64()} 311 } 312 res := []float64{} 313 for i := 0; i < values.Len(); i++ { 314 v := values.Index(i).Interface() 315 res = append(res, Of(v).CFloat64()) 316 } 317 return res 318 } 319 320 // Bool returns <v> as bool 321 func (v Any) Bool() bool { 322 if v.value == nil { 323 return false 324 } 325 326 value, ok := v.value.(bool) 327 if !ok { 328 panic("v is not a type of bool") 329 } 330 return value 331 } 332 333 // CBool converts and returns <v> as bool 334 func (v Any) CBool() bool { 335 336 if v.value == nil { 337 return false 338 } 339 340 value, ok := v.value.(bool) 341 if ok { 342 return value 343 } 344 345 value, err := strconv.ParseBool(fmt.Sprintf("%v", v.value)) 346 if err != nil { 347 panic(err.Error()) 348 } 349 return value 350 } 351 352 // Number converts and returns <v> as num.Number 353 func (v Any) Number() *num.Number { 354 switch v.value.(type) { 355 case *num.Number: 356 return v.value.(*num.Number) 357 case num.Number: 358 value := v.value.(num.Number) 359 return &value 360 default: 361 return num.Of(v.value) 362 } 363 } 364 365 // Datetime converts and returns <v> as day.Datetime 366 func (v Any) Datetime() *day.Datetime { 367 switch v.value.(type) { 368 case *day.Datetime: 369 return v.value.(*day.Datetime) 370 case day.Datetime: 371 value := v.value.(day.Datetime) 372 return &value 373 default: 374 return day.Of(v.value) 375 } 376 } 377 378 // Map converts and returns <v> as maps.Map 379 func (v Any) Map() Map { 380 switch v.value.(type) { 381 case Map: 382 return v.value.(Map) 383 case maps.Map: 384 return Map{MapStrAny: v.value.(maps.Map)} 385 } 386 return MapOf(v.value) 387 } 388 389 // MapStr converts and returns <v> as maps.MapStr 390 func (v Any) MapStr() maps.MapStrAny { 391 switch v.value.(type) { 392 case Map: 393 return v.value.(Map).MapStrAny 394 case maps.Map: 395 return v.value.(maps.Map) 396 } 397 return MapOf(v.value).MapStrAny 398 } 399 400 // IsDatetime checks whether <v> is type of datetime. 401 func (v Any) IsDatetime() bool { 402 switch v.value.(type) { 403 case time.Time, *time.Time, day.Datetime, *day.Datetime: 404 return true 405 default: 406 return false 407 } 408 } 409 410 // IsNumber checks whether <v> is type of number. 411 func (v Any) IsNumber() bool { 412 switch v.value.(type) { 413 case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, complex64, complex128: 414 return true 415 default: 416 return false 417 } 418 } 419 420 // IsMap checks whether <v> is type of map. 421 func (v Any) IsMap() bool { 422 switch v.value.(type) { 423 case map[string]interface{}, maps.Map, Map: 424 return true 425 default: 426 typeof := reflect.TypeOf(v.value) 427 return typeof.Kind() == reflect.Map 428 } 429 } 430 431 // IsBool checks whether <v> is type of bool. 432 func (v Any) IsBool() bool { 433 switch v.value.(type) { 434 case bool: 435 return true 436 default: 437 return false 438 } 439 } 440 441 // IsInt checks whether <v> is type of int. 442 func (v Any) IsInt() bool { 443 switch v.value.(type) { 444 case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: 445 return true 446 default: 447 return false 448 } 449 } 450 451 // IsFloat checks whether <v> is type of float. 452 func (v Any) IsFloat() bool { 453 switch v.value.(type) { 454 case float32, float64: 455 return true 456 default: 457 return false 458 } 459 } 460 461 // IsString checks whether <v> is type of string. 462 func (v Any) IsString() bool { 463 switch v.value.(type) { 464 case string: 465 return true 466 default: 467 return false 468 } 469 } 470 471 // IsSlice checks whether <v> is type of slice. 472 func (v Any) IsSlice() bool { 473 values := reflect.ValueOf(v.value) 474 values = reflect.Indirect(values) 475 return values.Kind() == reflect.Slice 476 } 477 478 // IsArray checks whether <v> is type of array. 479 func (v Any) IsArray() bool { 480 values := reflect.ValueOf(v.value) 481 values = reflect.Indirect(values) 482 return values.Kind() == reflect.Array 483 } 484 485 // IsCollection checks whether <v> is type of array or slice. 486 func (v Any) IsCollection() bool { 487 values := reflect.ValueOf(v.value) 488 values = reflect.Indirect(values) 489 kind := values.Kind() 490 return kind == reflect.Array || kind == reflect.Slice 491 } 492 493 // IsNotNil checks whether <v> is not nil. 494 func (v Any) IsNotNil() bool { 495 return v.value != nil 496 } 497 498 // IsNil checks whether <v> is nil. 499 func (v Any) IsNil() bool { 500 return v.value == nil 501 } 502 503 // IsEmpty checks whether <v> is empty. 504 func (v Any) IsEmpty() bool { 505 if v.value == nil { 506 return true 507 } 508 509 if v.IsInt() { 510 return v.CInt() == 0 511 } 512 513 if v.IsFloat() { 514 return v.CFloat64() == 0.0 515 } 516 517 if v.IsBool() { 518 return v.Bool() == false 519 } 520 521 if v.IsCollection() { 522 return len(v.Interfaces()) == 0 523 } 524 525 str := v.CString() 526 return str == "" || str == "0" || strings.ToLower(str) == "false" || strings.ToLower(str) == "f" 527 } 528 529 // Scan for db scan 530 func (v *Any) Scan(src interface{}) error { 531 *v = *Of(src) 532 return nil 533 } 534 535 // Value for db driver value 536 func (v *Any) Value() (driver.Value, error) { 537 return v.value, nil 538 } 539 540 // MarshalJSON for json marshalJSON 541 func (v *Any) MarshalJSON() ([]byte, error) { 542 return json.Marshal(v.value) 543 } 544 545 // UnmarshalJSON for json marshalJSON 546 func (v *Any) UnmarshalJSON(data []byte) error { 547 *v = *Of(data) 548 return nil 549 }