storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/lifecycle/and.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2019 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package lifecycle
    18  
    19  import (
    20  	"encoding/xml"
    21  )
    22  
    23  var errDuplicateTagKey = Errorf("Duplicate Tag Keys are not allowed")
    24  
    25  // And - a tag to combine a prefix and multiple tags for lifecycle configuration rule.
    26  type And struct {
    27  	XMLName xml.Name `xml:"And"`
    28  	Prefix  Prefix   `xml:"Prefix,omitempty"`
    29  	Tags    []Tag    `xml:"Tag,omitempty"`
    30  }
    31  
    32  // isEmpty returns true if Tags field is null
    33  func (a And) isEmpty() bool {
    34  	return len(a.Tags) == 0 && !a.Prefix.set
    35  }
    36  
    37  // Validate - validates the And field
    38  func (a And) Validate() error {
    39  	emptyPrefix := !a.Prefix.set
    40  	emptyTags := len(a.Tags) == 0
    41  
    42  	if emptyPrefix && emptyTags {
    43  		return nil
    44  	}
    45  
    46  	if emptyPrefix && !emptyTags || !emptyPrefix && emptyTags {
    47  		return errXMLNotWellFormed
    48  	}
    49  
    50  	if a.ContainsDuplicateTag() {
    51  		return errDuplicateTagKey
    52  	}
    53  	for _, t := range a.Tags {
    54  		if err := t.Validate(); err != nil {
    55  			return err
    56  		}
    57  	}
    58  	return nil
    59  }
    60  
    61  // ContainsDuplicateTag - returns true if duplicate keys are present in And
    62  func (a And) ContainsDuplicateTag() bool {
    63  	x := make(map[string]struct{}, len(a.Tags))
    64  
    65  	for _, t := range a.Tags {
    66  		if _, has := x[t.Key]; has {
    67  			return true
    68  		}
    69  		x[t.Key] = struct{}{}
    70  	}
    71  
    72  	return false
    73  }