@@ -14,6 +14,8 @@ public struct Resource: Equatable, Hashable, Codable {
14
14
/// A dictionary of labels that describe the resource.
15
15
public var attributes : [ String : AttributeValue ]
16
16
17
+ public private( set) var entities : [ Entity ] = [ ]
18
+
17
19
/// Returns a default Resource.
18
20
public init ( ) {
19
21
let executableName = ProcessInfo . processInfo. processName
@@ -30,37 +32,80 @@ public struct Resource: Equatable, Hashable, Codable {
30
32
)
31
33
}
32
34
35
+ private static func mergeEntities( _ lhs: [ Entity ] , _ rhs: [ Entity ] ) -> [ Entity ] {
36
+ if lhs. isEmpty {
37
+ return rhs
38
+ }
39
+
40
+ if rhs. isEmpty {
41
+ return lhs
42
+ }
43
+ var entityMap = [ String: Entity] ( )
44
+ lhs. forEach { entityMap [ $0. type] = $0 }
45
+ rhs. forEach { entity in
46
+ if !entityMap. contains ( where: { key, _ in
47
+ entity. type == key
48
+ } ) {
49
+ entityMap [ entity. type] = entity
50
+ } else {
51
+ if let old = entityMap [ entity. type] {
52
+ let new = Entity . builder ( type: old. type)
53
+ . with ( identifiers: old. identifiers)
54
+ . with ( attributes: entity. attributes
55
+ . merging ( old. attributes) { _, old in old } )
56
+ . build ( )
57
+ entityMap [ entity. type] = new
58
+ }
59
+ }
60
+ }
61
+ return Array ( entityMap. values)
62
+ }
63
+
33
64
/// Returns an empty Resource.
34
65
static var empty : Resource {
35
66
return self . init ( attributes: [ String: AttributeValue] ( ) )
36
67
}
37
68
38
69
/// Returns a Resource.
39
70
/// - Parameter labels: a dictionary of labels that describe the resource.
40
- public init ( attributes: [ String : AttributeValue ] ) {
71
+ public init ( attributes: [ String : AttributeValue ] , entities: [ Entity ] = [ ] ) {
72
+ self . entities = entities
41
73
if Resource . checkAttributes ( attributes: attributes) {
42
- self . attributes = attributes
74
+ self . attributes = attributes. filter { key, _ in
75
+ for entity in entities {
76
+ if entity. attributes. contains ( where: { attribute in attribute. key == key } ) {
77
+ return true
78
+ }
79
+ if entity. identifiers. contains ( where: { attribute in attribute. key == key } ) {
80
+ return true
81
+ }
82
+ }
83
+ return false
84
+ }
43
85
} else {
44
86
self . attributes = [ String: AttributeValue] ( )
45
87
}
88
+
46
89
}
47
90
48
91
/// Modifies the current Resource by merging with the other Resource.
49
92
/// In case of a collision, new Resource takes precedence.
50
93
/// - Parameter other: the Resource that will be merged with this
51
94
public mutating func merge( other: Resource ) {
52
95
attributes. merge ( other. attributes) { _, other in other }
96
+ entities = Resource . mergeEntities ( entities, other. entities)
53
97
}
54
98
55
99
/// Returns a new, merged Resource by merging the current Resource with the other Resource.
56
100
/// In case of a collision, new Resource takes precedence.
57
101
/// - Parameter other: the Resource that will be merged with this
58
102
public func merging( other: Resource ) -> Resource {
59
103
let labelsCopy = attributes. merging ( other. attributes) { _, other in other }
60
- return Resource ( attributes: labelsCopy)
104
+ let entities = Resource . mergeEntities ( self . entities, other. entities)
105
+ return Resource ( attributes: labelsCopy, entities: entities)
61
106
}
62
107
63
- private static func checkAttributes( attributes: [ String : AttributeValue ] ) -> Bool {
108
+ internal static func checkAttributes( attributes: [ String : AttributeValue ] ) -> Bool {
64
109
for entry in attributes where !isValidAndNotEmpty( name: entry. key) {
65
110
return false
66
111
}
0 commit comments