func (c *ClientOptions) SetMaxConnIdleTime(d time.Duration) *ClientOptions {
	c.MaxConnIdleTime = &d
	return c
}
SetMaxConnIdleTime specifies the maximum amount of time that a connection will remain idle in a connection pool
before it is removed from the pool and closed. This can also be set through the "maxIdleTimeMS" URI option (e.g.
"maxIdleTimeMS=10000"). The default is 0, meaning a connection can remain unused indefinitely.
package options  
import (
	"bytes"
	"context"
	"crypto/tls"
	"crypto/x509"
	"encoding/pem"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"strings"
	"time"
	"github.com/youmark/pkcs8"
	"go.mongodb.org/mongo-driver/bson/bsoncodec"
	"go.mongodb.org/mongo-driver/event"
	"go.mongodb.org/mongo-driver/mongo/readconcern"
	"go.mongodb.org/mongo-driver/mongo/readpref"
	"go.mongodb.org/mongo-driver/mongo/writeconcern"
	"go.mongodb.org/mongo-driver/tag"
	"go.mongodb.org/mongo-driver/x/mongo/driver"
	"go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
	"go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage"
)
type ContextDialer interface {
	DialContext(ctx context.Context, network, address string) (net.Conn, error)
}
type Credential struct {
	AuthMechanism           string
	AuthMechanismProperties map[string]string
	AuthSource              string
	Username                string
	Password                string
	PasswordSet             bool
}
type ClientOptions struct {
	AppName                  *string
	Auth                     *Credential
	AutoEncryptionOptions    *AutoEncryptionOptions
	ConnectTimeout           *time.Duration
	Compressors              []string
	Dialer                   ContextDialer
	Direct                   *bool
	DisableOCSPEndpointCheck *bool
	HeartbeatInterval        *time.Duration
	Hosts                    []string
	LocalThreshold           *time.Duration
	MaxConnIdleTime          *time.Duration
	MaxPoolSize              *uint64
	MinPoolSize              *uint64
	PoolMonitor              *event.PoolMonitor
	Monitor                  *event.CommandMonitor
	ServerMonitor            *event.ServerMonitor
	ReadConcern              *readconcern.ReadConcern
	ReadPreference           *readpref.ReadPref
	Registry                 *bsoncodec.Registry
	ReplicaSet               *string
	RetryReads               *bool
	RetryWrites              *bool
	ServerSelectionTimeout   *time.Duration
	SocketTimeout            *time.Duration
	TLSConfig                *tls.Config
	WriteConcern             *writeconcern.WriteConcern
	ZlibLevel                *int
	ZstdLevel                *int
	err error
	uri string
	cs  *connstring.ConnString
	AuthenticateToAnything *bool
	Deployment driver.Deployment
}
func Client() *ClientOptions {
	return new(ClientOptions)
}
func (c *ClientOptions) Validate() error {
	c.validateAndSetError()
	return c.err
}
func (c *ClientOptions) validateAndSetError() {
	if c.err != nil {
		return
	}
	if c.Direct != nil && *c.Direct {
		if len(c.Hosts) > 1 {
			c.err = errors.New("a direct connection cannot be made if multiple hosts are specified")
			return
		}
		if c.cs != nil && c.cs.Scheme == connstring.SchemeMongoDBSRV {
			c.err = errors.New("a direct connection cannot be made if an SRV URI is used")
			return
		}
	}
}
func (c *ClientOptions) GetURI() string {
	return c.uri
}
func (c *ClientOptions) ApplyURI(uri string) *ClientOptions {
	if c.err != nil {
		return c
	}
	c.uri = uri
	cs, err := connstring.ParseAndValidate(uri)
	if err != nil {
		c.err = err
		return c
	}
	c.cs = &cs
	if cs.AppName != "" {
		c.AppName = &cs.AppName
	}
	if cs.HasAuthParameters() {
		c.Auth = &Credential{
			AuthMechanism:           cs.AuthMechanism,
			AuthMechanismProperties: cs.AuthMechanismProperties,
			AuthSource:              cs.AuthSource,
			Username:                cs.Username,
			Password:                cs.Password,
			PasswordSet:             cs.PasswordSet,
		}
	}
	if cs.ConnectSet {
		direct := cs.Connect == connstring.SingleConnect
		c.Direct = &direct
	}
	if cs.DirectConnectionSet {
		c.Direct = &cs.DirectConnection
	}
	if cs.ConnectTimeoutSet {
		c.ConnectTimeout = &cs.ConnectTimeout
	}
	if len(cs.Compressors) > 0 {
		c.Compressors = cs.Compressors
		if stringSliceContains(c.Compressors, "zlib") {
			defaultLevel := wiremessage.DefaultZlibLevel
			c.ZlibLevel = &defaultLevel
		}
		if stringSliceContains(c.Compressors, "zstd") {
			defaultLevel := wiremessage.DefaultZstdLevel
			c.ZstdLevel = &defaultLevel
		}
	}
	if cs.HeartbeatIntervalSet {
		c.HeartbeatInterval = &cs.HeartbeatInterval
	}
	c.Hosts = cs.Hosts
	if cs.LocalThresholdSet {
		c.LocalThreshold = &cs.LocalThreshold
	}
	if cs.MaxConnIdleTimeSet {
		c.MaxConnIdleTime = &cs.MaxConnIdleTime
	}
	if cs.MaxPoolSizeSet {
		c.MaxPoolSize = &cs.MaxPoolSize
	}
	if cs.MinPoolSizeSet {
		c.MinPoolSize = &cs.MinPoolSize
	}
	if cs.ReadConcernLevel != "" {
		c.ReadConcern = readconcern.New(readconcern.Level(cs.ReadConcernLevel))
	}
	if cs.ReadPreference != "" || len(cs.ReadPreferenceTagSets) > 0 || cs.MaxStalenessSet {
		opts := make([]readpref.Option, 0, 1)
		tagSets := tag.NewTagSetsFromMaps(cs.ReadPreferenceTagSets)
		if len(tagSets) > 0 {
			opts = append(opts, readpref.WithTagSets(tagSets...))
		}
		if cs.MaxStaleness != 0 {
			opts = append(opts, readpref.WithMaxStaleness(cs.MaxStaleness))
		}
		mode, err := readpref.ModeFromString(cs.ReadPreference)
		if err != nil {
			c.err = err
			return c
		}
		c.ReadPreference, c.err = readpref.New(mode, opts...)
		if c.err != nil {
			return c
		}
	}
	if cs.RetryWritesSet {
		c.RetryWrites = &cs.RetryWrites
	}
	if cs.RetryReadsSet {
		c.RetryReads = &cs.RetryReads
	}
	if cs.ReplicaSet != "" {
		c.ReplicaSet = &cs.ReplicaSet
	}
	if cs.ServerSelectionTimeoutSet {
		c.ServerSelectionTimeout = &cs.ServerSelectionTimeout
	}
	if cs.SocketTimeoutSet {
		c.SocketTimeout = &cs.SocketTimeout
	}
	if cs.SSL {
		tlsConfig := new(tls.Config)
		if cs.SSLCaFileSet {
			c.err = addCACertFromFile(tlsConfig, cs.SSLCaFile)
			if c.err != nil {
				return c
			}
		}
		if cs.SSLInsecure {
			tlsConfig.InsecureSkipVerify = true
		}
		var x509Subject string
		var keyPasswd string
		if cs.SSLClientCertificateKeyPasswordSet && cs.SSLClientCertificateKeyPassword != nil {
			keyPasswd = cs.SSLClientCertificateKeyPassword()
		}
		if cs.SSLClientCertificateKeyFileSet {
			x509Subject, err = addClientCertFromConcatenatedFile(tlsConfig, cs.SSLClientCertificateKeyFile, keyPasswd)
		} else if cs.SSLCertificateFileSet || cs.SSLPrivateKeyFileSet {
			x509Subject, err = addClientCertFromSeparateFiles(tlsConfig, cs.SSLCertificateFile,
				cs.SSLPrivateKeyFile, keyPasswd)
		}
		if err != nil {
			c.err = err
			return c
		}
		if c.Auth != nil && strings.ToLower(c.Auth.AuthMechanism) == "mongodb-x509" &&
			c.Auth.Username == "" {
			c.Auth.Username = extractX509UsernameFromSubject(x509Subject)
		}
		c.TLSConfig = tlsConfig
	}
	if cs.JSet || cs.WString != "" || cs.WNumberSet || cs.WTimeoutSet {
		opts := make([]writeconcern.Option, 0, 1)
		if len(cs.WString) > 0 {
			opts = append(opts, writeconcern.WTagSet(cs.WString))
		} else if cs.WNumberSet {
			opts = append(opts, writeconcern.W(cs.WNumber))
		}
		if cs.JSet {
			opts = append(opts, writeconcern.J(cs.J))
		}
		if cs.WTimeoutSet {
			opts = append(opts, writeconcern.WTimeout(cs.WTimeout))
		}
		c.WriteConcern = writeconcern.New(opts...)
	}
	if cs.ZlibLevelSet {
		c.ZlibLevel = &cs.ZlibLevel
	}
	if cs.ZstdLevelSet {
		c.ZstdLevel = &cs.ZstdLevel
	}
	if cs.SSLDisableOCSPEndpointCheckSet {
		c.DisableOCSPEndpointCheck = &cs.SSLDisableOCSPEndpointCheck
	}
	return c
}
func (c *ClientOptions) SetAppName(s string) *ClientOptions {
	c.AppName = &s
	return c
}
func (c *ClientOptions) SetAuth(auth Credential) *ClientOptions {
	c.Auth = &auth
	return c
}
func (c *ClientOptions) SetCompressors(comps []string) *ClientOptions {
	c.Compressors = comps
	return c
}
func (c *ClientOptions) SetConnectTimeout(d time.Duration) *ClientOptions {
	c.ConnectTimeout = &d
	return c
}
func (c *ClientOptions) SetDialer(d ContextDialer) *ClientOptions {
	c.Dialer = d
	return c
}
func (c *ClientOptions) SetDirect(b bool) *ClientOptions {
	c.Direct = &b
	return c
}
func (c *ClientOptions) SetHeartbeatInterval(d time.Duration) *ClientOptions {
	c.HeartbeatInterval = &d
	return c
}
func (c *ClientOptions) SetHosts(s []string) *ClientOptions {
	c.Hosts = s
	return c
}
func (c *ClientOptions) SetLocalThreshold(d time.Duration) *ClientOptions {
	c.LocalThreshold = &d
	return c
}