github.com/jwowillo/pipe@v1.2.0/produce.go (about)

     1  package pipe
     2  
     3  import "sync"
     4  
     5  // Producer produces Items to pass to Pipes.
     6  //
     7  // false is returned when the Producer is done producing. The Item returned
     8  // with the false value is ignored.
     9  type Producer interface {
    10  	Produce() (Item, bool)
    11  }
    12  
    13  // ProducerFunc converts a function to a Producer.
    14  type ProducerFunc func() (Item, bool)
    15  
    16  // Produce applies to the function.
    17  func (f ProducerFunc) Produce() (Item, bool) {
    18  	return f()
    19  }
    20  
    21  // ProduceAndProcess processes all the Items from the Producer with the Pipe.
    22  func ProduceAndProcess(p *Pipe, prod Producer) []Item {
    23  	n := 0
    24  	x, ok := prod.Produce()
    25  	for ok {
    26  		n++
    27  		p.Receive(x)
    28  		x, ok = prod.Produce()
    29  	}
    30  	xs := make([]Item, n)
    31  	for i := 0; i < n; i++ {
    32  		xs[i] = p.Deliver()
    33  	}
    34  	return xs
    35  }
    36  
    37  // ProduceProcessAndConsume process all the Items from the Producer with the
    38  // Pipe and gives them to the Consumer as they are delivered.
    39  func ProduceProcessAndConsume(p *Pipe, prod Producer, c Consumer) {
    40  	n := 0
    41  	x, ok := prod.Produce()
    42  	for ok {
    43  		n++
    44  		p.Receive(x)
    45  		x, ok = prod.Produce()
    46  	}
    47  	var wg sync.WaitGroup
    48  	wg.Add(n)
    49  	for i := 0; i < n; i++ {
    50  		go func() {
    51  			c.Consume(p.Deliver())
    52  			wg.Done()
    53  		}()
    54  	}
    55  	wg.Wait()
    56  }