github.com/tursom/GoCollections@v0.3.10/concurrent/future/mapper.go (about) 1 package future 2 3 import ( 4 "github.com/tursom/GoCollections/exceptions" 5 "github.com/tursom/GoCollections/lang" 6 "github.com/tursom/GoCollections/util/time" 7 ) 8 9 type ( 10 mapperFuture[V1, V2 any] struct { 11 future Future[V1] 12 mapper func(v1 V1) (V2, exceptions.Exception) 13 v V2 14 e exceptions.Exception 15 done bool 16 } 17 ) 18 19 func Map[V1, V2 any]( 20 future Future[V1], 21 mapper func(v1 V1) (V2, exceptions.Exception), 22 ) Future[V2] { 23 return &mapperFuture[V1, V2]{ 24 future: future, 25 mapper: mapper, 26 } 27 } 28 29 func (m *mapperFuture[V1, V2]) Get() (V2, exceptions.Exception) { 30 if m.done { 31 return m.v, m.e 32 } 33 34 defer func() { 35 m.done = true 36 }() 37 38 v1, e := m.future.Get() 39 if e != nil { 40 m.e = e 41 return lang.Nil[V2](), e 42 } 43 44 v2, e := m.mapper(v1) 45 if e != nil { 46 m.e = e 47 return lang.Nil[V2](), e 48 } 49 50 m.v = v2 51 return v2, nil 52 } 53 54 func (m *mapperFuture[V1, V2]) GetT(timeout time.Duration) (V2, exceptions.Exception) { 55 if m.done { 56 return m.v, m.e 57 } 58 59 v1, e := m.future.GetT(timeout) 60 if e != nil { 61 return m.processException(e) 62 } 63 64 v2, e := m.mapper(v1) 65 if e != nil { 66 return m.processException(e) 67 } 68 69 m.v = v2 70 return v2, nil 71 } 72 73 func (m *mapperFuture[V1, V2]) processException(e exceptions.Exception) (V2, exceptions.Exception) { 74 if _, ok := e.(*exceptions.TimeoutException); !ok { 75 m.done = true 76 m.e = e 77 } 78 return lang.Nil[V2](), e 79 } 80 81 func (m *mapperFuture[V1, V2]) IsDone() bool { 82 return m.future.IsDone() 83 } 84 85 func (m *mapperFuture[V1, V2]) IsCancelled() bool { 86 return m.future.IsCancelled() 87 } 88 89 func (m *mapperFuture[V1, V2]) Cancel() bool { 90 return m.future.Cancel() 91 }