github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/infra/conf/merge/rules.go (about)

     1  // Copyright 2020 Jebbs. All rights reserved.
     2  // Use of this source code is governed by MIT
     3  // license that can be found in the LICENSE file.
     4  
     5  package merge
     6  
     7  const (
     8  	priorityKey string = "_priority"
     9  	tagKey      string = "_tag"
    10  )
    11  
    12  // ApplyRules applies merge rules according to _tag, _priority fields, and remove them
    13  func ApplyRules(m map[string]interface{}) error {
    14  	err := sortMergeSlices(m)
    15  	if err != nil {
    16  		return err
    17  	}
    18  	removeHelperFields(m)
    19  	return nil
    20  }
    21  
    22  // sortMergeSlices enumerates all slices in a map, to sort by priority and merge by tag
    23  func sortMergeSlices(target map[string]interface{}) error {
    24  	for key, value := range target {
    25  		if slice, ok := value.([]interface{}); ok {
    26  			sortByPriority(slice)
    27  			s, err := mergeSameTag(slice)
    28  			if err != nil {
    29  				return err
    30  			}
    31  			target[key] = s
    32  			for _, item := range s {
    33  				if m, ok := item.(map[string]interface{}); ok {
    34  					sortMergeSlices(m)
    35  				}
    36  			}
    37  		} else if field, ok := value.(map[string]interface{}); ok {
    38  			sortMergeSlices(field)
    39  		}
    40  	}
    41  	return nil
    42  }
    43  
    44  func removeHelperFields(target map[string]interface{}) {
    45  	for key, value := range target {
    46  		if key == priorityKey || key == tagKey {
    47  			delete(target, key)
    48  		} else if slice, ok := value.([]interface{}); ok {
    49  			for _, e := range slice {
    50  				if el, ok := e.(map[string]interface{}); ok {
    51  					removeHelperFields(el)
    52  				}
    53  			}
    54  		} else if field, ok := value.(map[string]interface{}); ok {
    55  			removeHelperFields(field)
    56  		}
    57  	}
    58  }