github.com/opentofu/opentofu@v1.7.1/internal/configs/configschema/filter.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package configschema
     7  
     8  type FilterT[T any] func(string, T) bool
     9  
    10  var (
    11  	FilterReadOnlyAttribute = func(name string, attribute *Attribute) bool {
    12  		return attribute.Computed && !attribute.Optional
    13  	}
    14  
    15  	FilterHelperSchemaIdAttribute = func(name string, attribute *Attribute) bool {
    16  		if name == "id" && attribute.Computed && attribute.Optional {
    17  			return true
    18  		}
    19  		return false
    20  	}
    21  
    22  	FilterDeprecatedAttribute = func(name string, attribute *Attribute) bool {
    23  		return attribute.Deprecated
    24  	}
    25  
    26  	FilterDeprecatedBlock = func(name string, block *NestedBlock) bool {
    27  		return block.Deprecated
    28  	}
    29  )
    30  
    31  func FilterOr[T any](filters ...FilterT[T]) FilterT[T] {
    32  	return func(name string, value T) bool {
    33  		for _, f := range filters {
    34  			if f(name, value) {
    35  				return true
    36  			}
    37  		}
    38  		return false
    39  	}
    40  }
    41  
    42  func (b *Block) Filter(filterAttribute FilterT[*Attribute], filterBlock FilterT[*NestedBlock]) *Block {
    43  	ret := &Block{
    44  		Description:     b.Description,
    45  		DescriptionKind: b.DescriptionKind,
    46  		Deprecated:      b.Deprecated,
    47  	}
    48  
    49  	if b.Attributes != nil {
    50  		ret.Attributes = make(map[string]*Attribute, len(b.Attributes))
    51  	}
    52  	for name, attrS := range b.Attributes {
    53  		if filterAttribute == nil || !filterAttribute(name, attrS) {
    54  			ret.Attributes[name] = attrS
    55  		}
    56  
    57  		if attrS.NestedType != nil {
    58  			ret.Attributes[name].NestedType = filterNestedType(attrS.NestedType, filterAttribute)
    59  		}
    60  	}
    61  
    62  	if b.BlockTypes != nil {
    63  		ret.BlockTypes = make(map[string]*NestedBlock, len(b.BlockTypes))
    64  	}
    65  	for name, blockS := range b.BlockTypes {
    66  		if filterBlock == nil || !filterBlock(name, blockS) {
    67  			block := blockS.Filter(filterAttribute, filterBlock)
    68  			ret.BlockTypes[name] = &NestedBlock{
    69  				Block:    *block,
    70  				Nesting:  blockS.Nesting,
    71  				MinItems: blockS.MinItems,
    72  				MaxItems: blockS.MaxItems,
    73  			}
    74  		}
    75  	}
    76  
    77  	return ret
    78  }
    79  
    80  func filterNestedType(obj *Object, filterAttribute FilterT[*Attribute]) *Object {
    81  	if obj == nil {
    82  		return nil
    83  	}
    84  
    85  	ret := &Object{
    86  		Attributes: map[string]*Attribute{},
    87  		Nesting:    obj.Nesting,
    88  	}
    89  
    90  	for name, attrS := range obj.Attributes {
    91  		if filterAttribute == nil || !filterAttribute(name, attrS) {
    92  			ret.Attributes[name] = attrS
    93  			if attrS.NestedType != nil {
    94  				ret.Attributes[name].NestedType = filterNestedType(attrS.NestedType, filterAttribute)
    95  			}
    96  		}
    97  	}
    98  
    99  	return ret
   100  }