func (s *Store) Has(name string) (exists bool, err error) {
	input := &s3.GetObjectInput{
		Bucket: aws.String(s.bucketName),
		Key:    aws.String(s.prefix + "/" + name),
	}
	_, err = s.data.GetObject(input)
	if err != nil {
		if aerr, ok := err.(awserr.Error); ok {  
			switch aerr.Code() {
			case s3.ErrCodeNoSuchKey:
				return false, nil
			default:
				return false, fmt.Errorf("%s failed to retrieve object %s. %w\n", moduleLogMessage, name, err)
			}
		}
	}
	return true, nil
}
Has function return true or false for either the object exists or not in the s3 bucket.
receives a string with the path to the object.
returns a boolean (true if object exists, false otherwise) and an error in case of unexpected behaviour.
package s3
import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/aws/aws-sdk-go/service/s3/s3iface"
	"github.com/brunotm/replicant/store"
	"github.com/brunotm/replicant/transaction"
	"net/url"
	"strings"
)
var _ store.Store = (*Store)(nil)
const moduleLogMessage = "store/s3:"
func init() {
	store.Register("s3",
		func(uri string) (s store.Store, err error) {
			return New(uri)
		})
}
type Store struct {
	data       s3iface.S3API  
	bucketName string         
	prefix     string         
}
func New(uri string) (*Store, error) {
	var err error
	u, err := url.Parse(uri)
	if err != nil {
		return nil, fmt.Errorf("%s failed to parse URI %s. Upstream error %w\n", moduleLogMessage, uri, err)
	}
	if u.Scheme != "s3" {
		return nil, fmt.Errorf("%s invalid S3 scheme in URI %s. Scheme is %s. Upstream error %w\n", moduleLogMessage, uri, u.Scheme, fmt.Errorf("Invalid S3 URI"))
	}
	var awsconfig *aws.Config = aws.NewConfig()
	var creds *credentials.Credentials
	var sess *session.Session
	secretKey, hasPassword := u.User.Password()
	if hasPassword {  
		creds = credentials.NewStaticCredentialsFromCreds(credentials.Value{
			AccessKeyID:     u.User.Username(),
			SecretAccessKey: secretKey,
		})
		awsconfig.WithCredentials(creds)
	}
	if reg, ok := u.Query()["region"]; ok {  
		sess, err = session.NewSession(awsconfig.WithRegion(reg[0]))
		if err != nil {
			return nil, fmt.Errorf("%s failed to create session. Upstream error %w\n", moduleLogMessage, err)
		}
	}
	svc := s3.New(sess)
	return &Store{data: svc, bucketName: u.Host, prefix: strings.Replace(u.Path, "/", "", 1)}, nil
}
func (s *Store) Close() (err error) {
	return nil
}
func (s *Store) Delete(name string) error {
	input := &s3.DeleteObjectInput{
		Bucket: aws.String(s.bucketName),
		Key:    aws.String(s.prefix + "/" + name),
	}
	_, err := s.data.DeleteObject(input)
	if err != nil {
		return fmt.Errorf("%s failed to delete object %s. Upstream error %w\n", moduleLogMessage, name, err)
	}
	return nil
}
func (s *Store) Get(name string) (config transaction.Config, err error) {
	input := &s3.GetObjectInput{
		Bucket: aws.String(s.bucketName),
		Key:    aws.String(s.prefix + "/" + name),
	}
	result, err := s.data.GetObject(input)
	if err != nil {
		if aerr, ok := err.(awserr.Error); ok {  
			switch aerr.Code() {
			case s3.ErrCodeNoSuchKey:
				return config, fmt.Errorf("%s transaction %s not found. %w\n", moduleLogMessage, input.Key, store.ErrTransactionNotFound)
			default:
				return config, fmt.Errorf("%s failed to retrieve object %s. %w\n", moduleLogMessage, input.Key, err)
			}
		}
	}
	buf := new(bytes.Buffer)
	buf.ReadFrom(result.Body)
	err = json.Unmarshal(buf.Bytes(), &config)
	if err != nil {
		return config, err
	}
	return config, nil
}