func WithPaths(paths []string, recursive bool) Conf {
	return func(m *MultiReader) error {
		if paths == nil {
			return errors.Wrap(ErrNoReader, "WithPaths: nil paths")
		}
		if len(paths) == 0 {
			return errors.Wrap(ErrNoReader, "WithPaths: empty paths")
		}
		files, err := tools.Files(recursive, paths...)
		if err != nil {
			return errors.Wrap(err, "WithPaths")
		}
		for _, name := range files {
			name := name
			c := &container{
				get: func() (io.ReadCloser, error) {
					m.currentName = name
					f, err := os.Open(name)
					return f, err
				},
			}
			m.readers = append(m.readers, c)
		}
		return nil
	}
}
WithPaths searches through the path and adds any files it finds to the
MultiReader. Each path will become its reader's name in the process. It
returns an error if any of given files are not found. It ignores any files
that cannot be read or opened.
package reader
import (
	"io"
	"io/ioutil"
	"os"
	"github.com/arsham/blush/internal/tools"
	"github.com/pkg/errors"
)
var ErrNoReader = errors.New("no input")
type MultiReader struct {
	readers     []*container
	currentName string
}
func NewMultiReader(input ...Conf) (*MultiReader, error) {
	m := &MultiReader{
		readers: make([]*container, 0),
	}
	for _, c := range input {
		if c == nil {
			return nil, ErrNoReader
		}
		err := c(m)
		if err != nil {
			return nil, err
		}
	}
	return m, nil
}
type Conf func(*MultiReader) error
func WithReader(name string, r io.ReadCloser) Conf {
	return func(m *MultiReader) error {
		if r == nil {
			return errors.Wrap(ErrNoReader, "WithReader")
		}
		c := &container{
			get: func() (io.ReadCloser, error) {
				m.currentName = name
				return r, nil
			},
		}
		m.readers = append(m.readers, c)
		return nil
	}
}