func All(expectOpts ...ExpectOpt) ExpectOpt {
	return func(opts *ExpectOpts) error {
		var options ExpectOpts
		for _, opt := range expectOpts {
			if err := opt(&options); err != nil {
				return err
			}
		}
		opts.Matchers = append(opts.Matchers, &allMatcher{
			options: options,
		})
		return nil
	}
}
All adds an Expect condition to exit if the content read from Console's tty
matches all of the provided ExpectOpt, in any order.
package expect
import (
	"bytes"
	"io"
	"os"
	"regexp"
	"strings"
	"syscall"
	"time"
)
type ExpectOpt func(*ExpectOpts) error
func WithTimeout(timeout time.Duration) ExpectOpt {
	return func(opts *ExpectOpts) error {
		opts.ReadTimeout = &timeout
		return nil
	}
}
type ConsoleCallback func(buf *bytes.Buffer) error
func (eo ExpectOpt) Then(f ConsoleCallback) ExpectOpt {
	return func(opts *ExpectOpts) error {
		var options ExpectOpts
		err := eo(&options)
		if err != nil {
			return err
		}
		for _, matcher := range options.Matchers {
			opts.Matchers = append(opts.Matchers, &callbackMatcher{
				f:       f,
				matcher: matcher,
			})
		}
		return nil
	}
}
type ExpectOpts struct {
	Matchers    []Matcher
	ReadTimeout *time.Duration
}
func (eo ExpectOpts) Match(v interface{}) Matcher {
	for _, matcher := range eo.Matchers {
		if matcher.Match(v) {
			return matcher
		}
	}
	return nil
}
type CallbackMatcher interface {
	Callback(buf *bytes.Buffer) error
}
type Matcher interface {
	Match(v interface{}) bool
	Criteria() interface{}
}
type callbackMatcher struct {
	f       ConsoleCallback
	matcher Matcher
}
func (cm *callbackMatcher) Match(v interface{}) bool {
	return cm.matcher.Match(v)
}
func (cm *callbackMatcher) Criteria() interface{} {
	return cm.matcher.Criteria()
}
func (cm *callbackMatcher) Callback(buf *bytes.Buffer) error {
	cb, ok := cm.matcher.(CallbackMatcher)
	if ok {
		err := cb.Callback(buf)
		if err != nil {
			return err
		}
	}
	err := cm.f(buf)
	if err != nil {
		return err
	}
	return nil
}
type errorMatcher struct {
	err error
}
func (em *errorMatcher) Match(v interface{}) bool {
	err, ok := v.(error)
	if !ok {
		return false
	}
	return err == em.err
}
func (em *errorMatcher) Criteria() interface{} {
	return em.err
}
type pathErrorMatcher struct {
	pathError os.PathError
}
func (em *pathErrorMatcher) Match(v interface{}) bool {
	pathError, ok := v.(*os.PathError)
	if !ok {
		return false
	}
	return *pathError == em.pathError
}
func (em *pathErrorMatcher) Criteria() interface{} {
	return em.pathError
}
type stringMatcher struct {
	str string
}
func (sm *stringMatcher) Match(v interface{}) bool {
	buf, ok := v.(*bytes.Buffer)
	if !ok {
		return false
	}
	if strings.Contains(buf.String(), sm.str) {
		return true
	}
	return false
}
func (sm *stringMatcher) Criteria() interface{} {
	return sm.str
}
type regexpMatcher struct {
	re *regexp.Regexp
}
func (rm *regexpMatcher) Match(v interface{}) bool {
	buf, ok := v.(*bytes.Buffer)
	if !ok {
		return false
	}
	return rm.re.Match(buf.Bytes())
}
func (rm *regexpMatcher) Criteria() interface{} {
	return rm.re
}
type allMatcher struct {
	options ExpectOpts
}
func (am *allMatcher) Match(v interface{}) bool {
	var matchers []Matcher
	for _, matcher := range am.options.Matchers {
		if matcher.Match(v) {
			continue
		}
		matchers = append(matchers, matcher)
	}
	am.options.Matchers = matchers
	return len(matchers) == 0
}
func (am *allMatcher) Criteria() interface{} {
	var criterias []interface{}
	for _, matcher := range am.options.Matchers {
		criterias = append(criterias, matcher.Criteria())
	}
	return criterias
}