@@ -28,6 +28,43 @@ impl Data {
28
28
. map ( Into :: into)
29
29
}
30
30
31
+ pub fn merge ( entries : & [ Data ] ) -> Data {
32
+ let mut merged_data = Data :: default ( ) ;
33
+ merged_data
34
+ . types
35
+ . extend ( entries. iter ( ) . flat_map ( |e| & e. types ) . cloned ( ) ) ;
36
+ // Now sort and remove types with the same guid.
37
+ merged_data
38
+ . types
39
+ . sort_unstable_by ( |a, b| a. guid . cmp ( & b. guid ) ) ;
40
+ merged_data. types . dedup_by_key ( |ty| ty. guid ) ;
41
+ merged_data
42
+ . functions
43
+ . extend ( entries. iter ( ) . flat_map ( |e| & e. functions ) . cloned ( ) ) ;
44
+ // Now sort and remove functions with the same symbol and guid.
45
+ merged_data
46
+ . functions
47
+ . sort_unstable_by ( |a, b| a. symbol . name . cmp ( & b. symbol . name ) ) ;
48
+ merged_data. functions . dedup_by ( |a, b| {
49
+ if a. guid == b. guid {
50
+ // Keep `a`s constraints.
51
+ b. constraints
52
+ . adjacent
53
+ . extend ( a. constraints . adjacent . clone ( ) ) ;
54
+ b. constraints
55
+ . call_sites
56
+ . extend ( a. constraints . call_sites . clone ( ) ) ;
57
+ b. constraints
58
+ . caller_sites
59
+ . extend ( a. constraints . caller_sites . clone ( ) ) ;
60
+ true
61
+ } else {
62
+ false
63
+ }
64
+ } ) ;
65
+ merged_data
66
+ }
67
+
31
68
pub fn to_bytes ( & self ) -> Vec < u8 > {
32
69
let mut builder = FlatBufferBuilder :: new ( ) ;
33
70
let fb_data = self . create ( & mut builder) ;
@@ -65,3 +102,73 @@ impl From<fb::Data<'_>> for Data {
65
102
}
66
103
}
67
104
}
105
+
106
+ #[ cfg( test) ]
107
+ mod tests {
108
+ use super :: * ;
109
+ use crate :: r#type:: guid:: TypeGUID ;
110
+ use crate :: r#type:: ComputedType ;
111
+ use crate :: signature:: function:: { Function , FunctionGUID } ;
112
+ use crate :: symbol:: class:: SymbolClass ;
113
+ use crate :: symbol:: Symbol ;
114
+ use uuid:: { uuid, Uuid } ;
115
+
116
+ const FUNC1_GUID : Uuid = uuid ! ( "6b50fa09-c8c5-4e88-b317-5a96c01c52ee" ) ;
117
+ const FUNC2_GUID : Uuid = uuid ! ( "e0565a4e-d730-4073-916c-fa6cb8ad2407" ) ;
118
+ const FUNC3_GUID : Uuid = uuid ! ( "5a7eb124-b786-4aa8-af2f-ccffbb600d21" ) ;
119
+
120
+ const TYPE1_GUID : Uuid = uuid ! ( "7aee6520-0443-4a91-910e-da068571fa7a" ) ;
121
+ const TYPE2_GUID : Uuid = uuid ! ( "9e8a58f0-757d-4fa6-8c41-a4da023c5a32" ) ;
122
+ const TYPE3_GUID : Uuid = uuid ! ( "f81a46df-ad7b-4d7b-a4a7-23ed22ab01ec" ) ;
123
+
124
+ // Used with `test_merge` test.
125
+ fn create_sample_function < T : Into < FunctionGUID > > ( name : & str , guid : T ) -> Function {
126
+ Function {
127
+ symbol : Symbol {
128
+ name : name. to_string ( ) ,
129
+ modifiers : Default :: default ( ) ,
130
+ class : SymbolClass :: Function ,
131
+ } ,
132
+ guid : guid. into ( ) ,
133
+ constraints : Default :: default ( ) ,
134
+ ty : rand:: random ( ) ,
135
+ entry : None ,
136
+ }
137
+ }
138
+
139
+ // Used with `test_merge` test.
140
+ fn create_sample_computed_type < T : Into < TypeGUID > > ( guid : T ) -> ComputedType {
141
+ let mut comp_ty = ComputedType :: new ( rand:: random ( ) ) ;
142
+ comp_ty. guid = guid. into ( ) ; // Adjust the guid for testing.
143
+ comp_ty
144
+ }
145
+
146
+ #[ test]
147
+ fn test_merge ( ) {
148
+ let first_data = Data :: new (
149
+ vec ! [
150
+ create_sample_function( "func1" , FUNC1_GUID ) ,
151
+ create_sample_function( "func2" , FUNC2_GUID ) ,
152
+ ] ,
153
+ vec ! [
154
+ create_sample_computed_type( TYPE1_GUID ) ,
155
+ create_sample_computed_type( TYPE2_GUID ) ,
156
+ ] ,
157
+ ) ;
158
+
159
+ let second_data = Data :: new (
160
+ vec ! [
161
+ create_sample_function( "func2" , FUNC2_GUID ) ,
162
+ create_sample_function( "func3" , FUNC3_GUID ) ,
163
+ ] ,
164
+ vec ! [
165
+ create_sample_computed_type( TYPE1_GUID ) ,
166
+ create_sample_computed_type( TYPE3_GUID ) ,
167
+ ] ,
168
+ ) ;
169
+
170
+ let merged_data = Data :: merge ( & [ first_data, second_data] ) ;
171
+ assert_eq ! ( merged_data. functions. len( ) , 3 , "{:#?}" , merged_data. functions) ;
172
+ assert_eq ! ( merged_data. types. len( ) , 3 , "{:#?}" , merged_data. types) ;
173
+ }
174
+ }
0 commit comments