github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/configs/configschema/filter.go (about)

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