func (b *BucketNotification) AddTopic(topicConfig NotificationConfig) bool {
	newTopicConfig := TopicConfig{NotificationConfig: topicConfig, Topic: topicConfig.Arn.String()}
	for _, n := range b.TopicConfigs {
		if n.Topic == newTopicConfig.Arn.String() && newTopicConfig.Filter == n.Filter {
			existingConfig := set.NewStringSet()
			for _, v := range n.Events {
				existingConfig.Add(string(v))
			}
			newConfig := set.NewStringSet()
			for _, v := range topicConfig.Events {
				newConfig.Add(string(v))
			}
			if !newConfig.Intersection(existingConfig).IsEmpty() {
				return false
			}
		}
	}
	b.TopicConfigs = append(b.TopicConfigs, newTopicConfig)
	return true
}
AddTopic adds a given topic config to the general bucket notification config
package minio
import (
	"encoding/xml"
	"errors"
	"fmt"
	"github.com/minio/minio-go/v6/pkg/set"
)
type NotificationEventType string
const (
	ObjectCreatedAll                     NotificationEventType = "s3:ObjectCreated:*"
	ObjectCreatedPut                                           = "s3:ObjectCreated:Put"
	ObjectCreatedPost                                          = "s3:ObjectCreated:Post"
	ObjectCreatedCopy                                          = "s3:ObjectCreated:Copy"
	ObjectCreatedCompleteMultipartUpload                       = "s3:ObjectCreated:CompleteMultipartUpload"
	ObjectAccessedGet                                          = "s3:ObjectAccessed:Get"
	ObjectAccessedHead                                         = "s3:ObjectAccessed:Head"
	ObjectAccessedAll                                          = "s3:ObjectAccessed:*"
	ObjectRemovedAll                                           = "s3:ObjectRemoved:*"
	ObjectRemovedDelete                                        = "s3:ObjectRemoved:Delete"
	ObjectRemovedDeleteMarkerCreated                           = "s3:ObjectRemoved:DeleteMarkerCreated"
	ObjectReducedRedundancyLostObject                          = "s3:ReducedRedundancyLostObject"
)
type FilterRule struct {
	Name  string `xml:"Name"`
	Value string `xml:"Value"`
}
type S3Key struct {
	FilterRules []FilterRule `xml:"FilterRule,omitempty"`
}
type Filter struct {
	S3Key S3Key `xml:"S3Key,omitempty"`
}
type Arn struct {
	Partition string
	Service   string
	Region    string
	AccountID string
	Resource  string
}
func NewArn(partition, service, region, accountID, resource string) Arn {
	return Arn{Partition: partition,
		Service:   service,
		Region:    region,
		AccountID: accountID,
		Resource:  resource}
}
func (arn Arn) String() string {
	return "arn:" + arn.Partition + ":" + arn.Service + ":" + arn.Region + ":" + arn.AccountID + ":" + arn.Resource
}
type NotificationConfig struct {
	ID     string                  `xml:"Id,omitempty"`
	Arn    Arn                     `xml:"-"`
	Events []NotificationEventType `xml:"Event"`
	Filter *Filter                 `xml:"Filter,omitempty"`
}
func NewNotificationConfig(arn Arn) NotificationConfig {
	return NotificationConfig{Arn: arn, Filter: &Filter{}}
}
func (t *NotificationConfig) AddEvents(events ...NotificationEventType) {
	t.Events = append(t.Events, events...)
}
func (t *NotificationConfig) AddFilterSuffix(suffix string) {
	if t.Filter == nil {
		t.Filter = &Filter{}
	}
	newFilterRule := FilterRule{Name: "suffix", Value: suffix}
	for index := range t.Filter.S3Key.FilterRules {
		if t.Filter.S3Key.FilterRules[index].Name == "suffix" {
			t.Filter.S3Key.FilterRules[index] = newFilterRule
			return
		}
	}
	t.Filter.S3Key.FilterRules = append(t.Filter.S3Key.FilterRules, newFilterRule)
}
func (t *NotificationConfig) AddFilterPrefix(prefix string) {
	if t.Filter == nil {
		t.Filter = &Filter{}
	}
	newFilterRule := FilterRule{Name: "prefix", Value: prefix}
	for index := range t.Filter.S3Key.FilterRules {
		if t.Filter.S3Key.FilterRules[index].Name == "prefix" {
			t.Filter.S3Key.FilterRules[index] = newFilterRule
			return
		}
	}
	t.Filter.S3Key.FilterRules = append(t.Filter.S3Key.FilterRules, newFilterRule)
}
func EqualNotificationEventTypeList(a, b []NotificationEventType) bool {
	if len(a) != len(b) {
		return false
	}
	setA := set.NewStringSet()
	for _, i := range a {
		setA.Add(string(i))
	}
	setB := set.NewStringSet()
	for _, i := range b {
		setB.Add(string(i))
	}
	return setA.Difference(setB).IsEmpty()
}
func EqualFilterRuleList(a, b []FilterRule) bool {
	if len(a) != len(b) {
		return false
	}
	setA := set.NewStringSet()
	for _, i := range a {
		setA.Add(fmt.Sprintf("%s-%s", i.Name, i.Value))
	}
	setB := set.NewStringSet()
	for _, i := range b {
		setB.Add(fmt.Sprintf("%s-%s", i.Name, i.Value))
	}
	return setA.Difference(setB).IsEmpty()
}
func (t *NotificationConfig) Equal(events []NotificationEventType, prefix, suffix string) bool {
	passEvents := EqualNotificationEventTypeList(t.Events, events)
	var newFilter []FilterRule
	if prefix != "" {
		newFilter = append(newFilter, FilterRule{Name: "prefix", Value: prefix})
	}
	if suffix != "" {
		newFilter = append(newFilter, FilterRule{Name: "suffix", Value: suffix})
	}
	passFilters := EqualFilterRuleList(t.Filter.S3Key.FilterRules, newFilter)
	return passEvents && passFilters
}
type TopicConfig struct {
	NotificationConfig
	Topic string `xml:"Topic"`
}
type QueueConfig struct {
	NotificationConfig
	Queue string `xml:"Queue"`
}
type LambdaConfig struct {
	NotificationConfig
	Lambda string `xml:"CloudFunction"`
}
type BucketNotification struct {
	XMLName       xml.Name       `xml:"NotificationConfiguration"`
	LambdaConfigs []LambdaConfig `xml:"CloudFunctionConfiguration"`
	TopicConfigs  []TopicConfig  `xml:"TopicConfiguration"`
	QueueConfigs  []QueueConfig  `xml:"QueueConfiguration"`
}