func (svc *S3) ForceDeleteBucket(name string) error {
	bucketName := svc.prefix + name
	_, err := svc.client.DeleteBucket(&SDK.DeleteBucketInput{
		Bucket: pointers.String(bucketName),
	})
	if err != nil {
		svc.Errorf("error on `DeleteBucket` operation; bucket=%s; error=%s;", name, err.Error())
		return err
	}
	svc.Infof("success on `DeleteBucket` operation; bucket=%s;", name)
	return nil
}
ForceDeleteBucket deletes S3 bucket by given name.
package s3
import (
	"strings"
	"sync"
	"github.com/aws/aws-sdk-go/aws/session"
	SDK "github.com/aws/aws-sdk-go/service/s3"
	"github.com/evalphobia/aws-sdk-go-wrapper/config"
	"github.com/evalphobia/aws-sdk-go-wrapper/log"
	"github.com/evalphobia/aws-sdk-go-wrapper/private/errors"
	"github.com/evalphobia/aws-sdk-go-wrapper/private/pointers"
)
const (
	serviceName = "s3"
)
type S3 struct {
	client   *SDK.S3
	endpoint string
	logger log.Logger
	prefix string
	bucketsMu sync.RWMutex
	buckets   map[string]*Bucket
}
func New(conf config.Config) (*S3, error) {
	sess, err := conf.Session()
	if err != nil {
		return nil, err
	}
	svc := NewFromSession(sess)
	svc.prefix = conf.DefaultPrefix
	return svc, nil
}
func NewFromSession(sess *session.Session) *S3 {
	cli := SDK.New(sess)
	return &S3{
		client:   cli,
		endpoint: cli.ClientInfo.Endpoint,
		logger:   log.DefaultLogger,
		buckets:  make(map[string]*Bucket),
	}
}
func (svc *S3) GetClient() *SDK.S3 {
	return svc.client
}
func (svc *S3) SetLogger(logger log.Logger) {
	svc.logger = logger
}
func (svc *S3) SetPrefix(prefix string) {
	svc.prefix = prefix
}
func (svc *S3) SetEndpoint(endpoint string) {
	svc.endpoint = endpoint
}
func (svc *S3) GetBucket(bucket string) (*Bucket, error) {
	bucketName := svc.prefix + bucket
	svc.bucketsMu.RLock()
	b, ok := svc.buckets[bucketName]
	svc.bucketsMu.RUnlock()
	if ok {
		return b, nil
	}
	_, err := svc.client.GetBucketLocation(&SDK.GetBucketLocationInput{
		Bucket: pointers.String(bucketName),
	})
	if err != nil {
		svc.Errorf("error on `GetQueueURL` operation; bueckt=%s; error=%s;", bucketName, err.Error())
		return nil, err
	}
	b = NewBucket(svc, bucket)
	svc.bucketsMu.Lock()
	svc.buckets[bucketName] = b
	svc.bucketsMu.Unlock()
	return b, nil
}
func (svc *S3) IsExistBucket(name string) (bool, error) {
	bucketName := svc.prefix + name
	data, err := svc.client.GetBucketLocation(&SDK.GetBucketLocationInput{
		Bucket: pointers.String(bucketName),
	})
	switch {
	case isNonSuchBucketError(err):
		return false, nil
	case err != nil:
		svc.Errorf("error on `GetQueueUrl` operation; queue=%s; error=%s", name, err.Error())
		return false, err
	case data != nil:
		return true, nil
	default:
		return false, nil
	}
}
func isNonSuchBucketError(err error) bool {
	const errNonSuchBucket = "NoSuchBucket: "
	if err == nil {
		return false
	}
	return strings.Contains(err.Error(), errNonSuchBucket)
}
func (svc *S3) CreateBucket(in *SDK.CreateBucketInput) error {
	data, err := svc.client.CreateBucket(in)
	if err != nil {
		svc.Errorf("error on `CreateBucket` operation; bucket=%s; error=%s;", *in.Bucket, err.Error())
		return err
	}
	svc.Infof("success on `CreateBucket` operation; bucket=%s; data=%s;", *in.Bucket, data.String())
	return nil
}
func (svc *S3) CreateBucketWithName(name string) error {
	bucketName := svc.prefix + name
	return svc.CreateBucket(&SDK.CreateBucketInput{
		Bucket: pointers.String(bucketName),
	})
}