github.com/influx6/npkg@v0.8.8/nbag/nbag.go (about) 1 package nbag 2 3 import ( 4 "context" 5 "sync" 6 "time" 7 ) 8 9 // Fields defines a map of key:value pairs. 10 type Fields map[interface{}]interface{} 11 12 // Getter defines a series of Get methods for which values will be retrieved with. 13 type Getter interface { 14 GetInt(interface{}) int 15 GetBool(interface{}) bool 16 GetInt8(interface{}) int8 17 GetInt16(interface{}) int16 18 GetInt32(interface{}) int32 19 GetInt64(interface{}) int64 20 Get(interface{}) interface{} 21 GetString(interface{}) string 22 GetFloat32(interface{}) float32 23 GetFloat64(interface{}) float64 24 GetDuration(interface{}) time.Duration 25 } 26 27 // ValueBag defines a context for holding values to be shared across processes.. 28 type ValueBag interface { 29 Getter 30 31 // Set adds a key-value pair into the bag. 32 Set(key, value interface{}) 33 34 // WithValue returns a new context then adds the key and value pair into the 35 // context's store. 36 WithValue(key interface{}, value interface{}) ValueBag 37 } 38 39 // vbag defines a struct for bundling a context against specific 40 // use cases with a explicitly set duration which clears all its internal 41 // data after the giving period. 42 type vbag struct { 43 ml sync.RWMutex 44 fields map[interface{}]interface{} 45 } 46 47 // ValueBagFrom adds giving key-value pairs into the bag. 48 func ValueBagFrom(fields map[interface{}]interface{}) ValueBag { 49 return &vbag{fields: fields} 50 } 51 52 // NewValueBag returns a new context object that meets the Context interface. 53 func NewValueBag() ValueBag { 54 return &vbag{ 55 fields: map[interface{}]interface{}{}, 56 } 57 } 58 59 // Set adds given value into context. 60 func (c *vbag) Set(key, value interface{}) { 61 c.ml.Lock() 62 defer c.ml.Unlock() 63 c.fields[key] = value 64 } 65 66 // WithValue returns a new context based on the previos one. 67 func (c *vbag) WithValue(key, value interface{}) ValueBag { 68 c.ml.RLock() 69 defer c.ml.RUnlock() 70 71 fields := make(map[interface{}]interface{}) 72 for k, v := range c.fields { 73 fields[k] = v 74 } 75 76 fields[key] = value 77 return ValueBagFrom(fields) 78 } 79 80 // Deadline returns giving time when context is expected to be canceled. 81 func (c *vbag) Deadline() time.Time { 82 return time.Time{} 83 } 84 85 // GetDuration returns the duration value of a key if it exists. 86 func (c *vbag) GetDuration(key interface{}) time.Duration { 87 val, found := c.get(key) 88 if !found { 89 return 0 90 } 91 92 if dval, ok := val.(time.Duration); ok { 93 return dval 94 } 95 96 if dval, ok := val.(int64); ok { 97 return time.Duration(dval) 98 } 99 100 if sval, ok := val.(string); ok { 101 if dur, err := time.ParseDuration(sval); err == nil { 102 return dur 103 } 104 } 105 106 return 0 107 } 108 109 // GetBool returns the bool value of a key if it exists. 110 func (c *vbag) GetBool(key interface{}) bool { 111 val, found := c.get(key) 112 if !found { 113 return false 114 } 115 116 return val.(bool) 117 118 } 119 120 // GetFloat64 returns the float64 value of a key if it exists. 121 func (c *vbag) GetFloat64(key interface{}) float64 { 122 val, found := c.get(key) 123 if !found { 124 return 0 125 } 126 127 return val.(float64) 128 129 } 130 131 // GetFloat32 returns the float32 value of a key if it exists. 132 func (c *vbag) GetFloat32(key interface{}) float32 { 133 val, found := c.get(key) 134 if !found { 135 return 0 136 } 137 138 return val.(float32) 139 140 } 141 142 // GetInt8 returns the int8 value of a key if it exists. 143 func (c *vbag) GetInt8(key interface{}) int8 { 144 val, found := c.get(key) 145 if !found { 146 return 0 147 } 148 149 return val.(int8) 150 151 } 152 153 // GetInt16 returns the int16 value of a key if it exists. 154 func (c *vbag) GetInt16(key interface{}) int16 { 155 val, found := c.get(key) 156 if !found { 157 return 0 158 } 159 160 return val.(int16) 161 162 } 163 164 // GetInt64 returns the value type value of a key if it exists. 165 func (c *vbag) GetInt64(key interface{}) int64 { 166 val, found := c.get(key) 167 if !found { 168 return 0 169 } 170 171 return val.(int64) 172 173 } 174 175 // GetInt32 returns the value type value of a key if it exists. 176 func (c *vbag) GetInt32(key interface{}) int32 { 177 val, found := c.get(key) 178 if !found { 179 return 0 180 } 181 182 return val.(int32) 183 184 } 185 186 // GetInt returns the value type value of a key if it exists. 187 func (c *vbag) GetInt(key interface{}) int { 188 val, found := c.get(key) 189 if !found { 190 return 0 191 } 192 193 return val.(int) 194 195 } 196 197 // GetString returns the value type value of a key if it exists. 198 func (c *vbag) GetString(key interface{}) string { 199 val, found := c.get(key) 200 if !found { 201 return "" 202 } 203 204 return val.(string) 205 206 } 207 208 // Get returns the value of a key if it exists. 209 func (c *vbag) Get(key interface{}) (value interface{}) { 210 item, _ := c.get(key) 211 return item 212 } 213 214 // Get returns the value of a key if it exists. 215 func (c *vbag) get(key interface{}) (value interface{}, found bool) { 216 c.ml.RLock() 217 defer c.ml.RUnlock() 218 219 item, ok := c.fields[key] 220 return item, ok 221 } 222 223 //============================================================================== 224 225 // googleContext implements a decorator for googles context package. 226 type googleContext struct { 227 context.Context 228 } 229 230 // FromContext returns a new context object that meets the Context interface. 231 func FromContext(ctx context.Context) *googleContext { 232 var gc googleContext 233 gc.Context = ctx 234 return &gc 235 } 236 237 // GetDuration returns the giving value for the provided key if it exists else nil. 238 func (g *googleContext) GetDuration(key interface{}) time.Duration { 239 val := g.Context.Value(key) 240 if val == nil { 241 return 0 242 } 243 244 if dval, ok := val.(time.Duration); ok { 245 return dval 246 } 247 248 if dval, ok := val.(int64); ok { 249 return time.Duration(dval) 250 } 251 252 if sval, ok := val.(string); ok { 253 if dur, err := time.ParseDuration(sval); err == nil { 254 return dur 255 } 256 } 257 258 return 0 259 } 260 261 // Get returns the giving value for the provided key if it exists else nil. 262 func (g *googleContext) Get(key interface{}) interface{} { 263 val := g.Context.Value(key) 264 if val == nil { 265 return val 266 } 267 268 return val 269 } 270 271 // GetBool returns the value type value of a key if it exists. 272 func (g *googleContext) GetBool(key interface{}) bool { 273 return g.Get(key).(bool) 274 } 275 276 // GetFloat64 returns the value type value of a key if it exists. 277 func (g *googleContext) GetFloat64(key interface{}) float64 { 278 return g.Get(key).(float64) 279 280 } 281 282 // GetFloat32 returns the value type value of a key if it exists. 283 func (g *googleContext) GetFloat32(key interface{}) float32 { 284 return g.Get(key).(float32) 285 } 286 287 // GetInt8 returns the value type value of a key if it exists. 288 func (g *googleContext) GetInt8(key interface{}) int8 { 289 return g.Get(key).(int8) 290 } 291 292 // GetInt16 returns the value type value of a key if it exists. 293 func (g *googleContext) GetInt16(key interface{}) int16 { 294 return g.Get(key).(int16) 295 } 296 297 // GetInt64 returns the value type value of a key if it exists. 298 func (g *googleContext) GetInt64(key interface{}) int64 { 299 return g.Get(key).(int64) 300 } 301 302 // GetInt32 returns the value type value of a key if it exists. 303 func (g *googleContext) GetInt32(key interface{}) int32 { 304 return g.Get(key).(int32) 305 } 306 307 // GetInt returns the value type value of a key if it exists. 308 func (g *googleContext) GetInt(key interface{}) int { 309 return g.Get(key).(int) 310 } 311 312 // GetString returns the value type value of a key if it exists. 313 func (g *googleContext) GetString(key interface{}) string { 314 return g.Get(key).(string) 315 } 316 317 //============================================================================== 318 319 // Pair defines a struct for storing a linked pair of key and values. 320 type Pair struct { 321 prev *Pair 322 key interface{} 323 value interface{} 324 } 325 326 // NewPair returns a a key-value pair chain for setting fields. 327 func NewPair(key, value interface{}) *Pair { 328 return &Pair{ 329 key: key, 330 value: value, 331 } 332 } 333 334 // Append returns a new Pair with the giving key and with the provded Pair set as 335 // it's previous link. 336 func Append(p *Pair, key, value interface{}) *Pair { 337 return p.Append(key, value) 338 } 339 340 // Fields returns all internal pair data as a map. 341 func (p *Pair) Fields() Fields { 342 var f Fields 343 344 if p.prev == nil { 345 f = make(Fields) 346 f[p.key] = p.value 347 return f 348 } 349 350 f = p.prev.Fields() 351 352 if p.key != "" { 353 f[p.key] = p.value 354 } 355 356 return f 357 } 358 359 // Append returns a new pair with the giving key and value and its previous 360 // set to this pair. 361 func (p *Pair) Append(key, val interface{}) *Pair { 362 return &Pair{ 363 prev: p, 364 key: key, 365 value: val, 366 } 367 } 368 369 // RemoveAll sets all key-value pairs to nil for all connected pair, till it reaches 370 // the root. 371 func (p *Pair) RemoveAll() { 372 p.key = nil 373 p.value = nil 374 375 if p.prev != nil { 376 p.prev.RemoveAll() 377 } 378 } 379 380 // Root returns the root Pair in the chain which links all pairs together. 381 func (p *Pair) Root() *Pair { 382 if p.prev == nil { 383 return p 384 } 385 386 return p.prev.Root() 387 } 388 389 // GetDuration returns the duration value of a key if it exists. 390 func (p *Pair) GetDuration(key interface{}) time.Duration { 391 val, found := p.Get(key) 392 if !found { 393 return 0 394 } 395 396 if dval, ok := val.(time.Duration); ok { 397 return dval 398 } 399 400 if dval, ok := val.(int64); ok { 401 return time.Duration(dval) 402 } 403 404 if sval, ok := val.(string); ok { 405 if dur, err := time.ParseDuration(sval); err == nil { 406 return dur 407 } 408 } 409 410 return 0 411 } 412 413 // GetBool returns the bool value of a key if it exists. 414 func (p *Pair) GetBool(key interface{}) bool { 415 val, found := p.Get(key) 416 if !found { 417 return false 418 } 419 420 return val.(bool) 421 422 } 423 424 // GetFloat64 returns the float64 value of a key if it exists. 425 func (p *Pair) GetFloat64(key interface{}) float64 { 426 val, found := p.Get(key) 427 if !found { 428 return 0 429 } 430 431 return val.(float64) 432 433 } 434 435 // GetFloat32 returns the float32 value of a key if it exists. 436 func (p *Pair) GetFloat32(key interface{}) float32 { 437 val, found := p.Get(key) 438 if !found { 439 return 0 440 } 441 442 return val.(float32) 443 444 } 445 446 // GetInt8 returns the int8 value of a key if it exists. 447 func (p *Pair) GetInt8(key interface{}) int8 { 448 val, found := p.Get(key) 449 if !found { 450 return 0 451 } 452 453 return val.(int8) 454 455 } 456 457 // GetInt16 returns the int16 value of a key if it exists. 458 func (p *Pair) GetInt16(key interface{}) int16 { 459 val, found := p.Get(key) 460 if !found { 461 return 0 462 } 463 464 return val.(int16) 465 466 } 467 468 // GetInt64 returns the value type value of a key if it exists. 469 func (p *Pair) GetInt64(key interface{}) int64 { 470 val, found := p.Get(key) 471 if !found { 472 return 0 473 } 474 475 return val.(int64) 476 477 } 478 479 // GetInt32 returns the value type value of a key if it exists. 480 func (p *Pair) GetInt32(key interface{}) int32 { 481 val, found := p.Get(key) 482 if !found { 483 return 0 484 } 485 486 return val.(int32) 487 488 } 489 490 // GetInt returns the value type value of a key if it exists. 491 func (p *Pair) GetInt(key interface{}) int { 492 val, found := p.Get(key) 493 if !found { 494 return 0 495 } 496 497 return val.(int) 498 499 } 500 501 // GetString returns the value type value of a key if it exists. 502 func (p *Pair) GetString(key interface{}) string { 503 val, found := p.Get(key) 504 if !found { 505 return "" 506 } 507 508 return val.(string) 509 510 } 511 512 // Get returns the value of a key if it exists. 513 func (p *Pair) Get(key interface{}) (interface{}, bool) { 514 if p == nil { 515 return nil, false 516 } 517 518 if p.key == key { 519 return p.value, true 520 } 521 522 if p.prev == nil { 523 return nil, false 524 } 525 526 return p.prev.Get(key) 527 }