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  }