@@ -137,26 +137,19 @@ impl Dictionary {
137
137
let mut attributes: Vec < DictionaryAttribute > = Vec :: new ( ) ;
138
138
let mut values: Vec < DictionaryValue > = Vec :: new ( ) ;
139
139
let mut vendors: Vec < DictionaryVendor > = Vec :: new ( ) ;
140
- let mut vendor_name: String = String :: new ( ) ;
141
-
142
- let reader = io:: BufReader :: new ( File :: open ( file_path) . map_err ( |error| RadiusError :: MalformedDictionaryError { error } ) ?) ;
143
- let lines = reader. lines ( )
144
- . filter_map ( Result :: ok)
145
- . filter ( |line| !line. is_empty ( ) )
146
- . filter ( |line| !line. contains ( & COMMENT_PREFIX ) ) ;
147
-
148
- for line in lines {
149
- let parsed_line: Vec < & str > = line. split_whitespace ( ) . filter ( |& item| !item. is_empty ( ) ) . collect ( ) ;
150
- match parsed_line[ 0 ] {
151
- "ATTRIBUTE" => parse_attribute ( parsed_line, & vendor_name, & mut attributes) ,
152
- "VALUE" => parse_value ( parsed_line, & vendor_name, & mut values) ,
153
- "VENDOR" => parse_vendor ( parsed_line, & mut vendors) ,
154
- "BEGIN-VENDOR" => { vendor_name. insert_str ( 0 , parsed_line[ 1 ] ) } ,
155
- "END-VENDOR" => { vendor_name. clear ( ) } ,
156
- _ => continue
157
- }
158
- } ;
159
- Ok ( Dictionary { attributes, values, vendors } )
140
+
141
+ match parse_file ( file_path, & mut attributes, & mut values, & mut vendors) {
142
+ Ok ( ( ) ) => Ok ( Dictionary { attributes, values, vendors } ) ,
143
+ Err ( error) => Err ( error)
144
+ }
145
+ }
146
+
147
+ /// Adds a dictionary file to existing Dictionary
148
+ ///
149
+ /// Processes attributes, values and vendors from supplied dictionary file
150
+ /// and adds them to existing attributes, values and vendors
151
+ pub fn add_file ( & mut self , file_path : & str ) -> Result < ( ) , RadiusError > {
152
+ parse_file ( file_path, & mut self . attributes , & mut self . values , & mut self . vendors )
160
153
}
161
154
162
155
/// Returns parsed DictionaryAttributes
@@ -198,6 +191,30 @@ fn assign_attribute_type(code_type: &str) -> Option<SupportedAttributeTypes> {
198
191
}
199
192
}
200
193
194
+ fn parse_file ( file_path : & str , attributes : & mut Vec < DictionaryAttribute > , values : & mut Vec < DictionaryValue > , vendors : & mut Vec < DictionaryVendor > ) -> Result < ( ) , RadiusError > {
195
+ let mut vendor_name: String = String :: new ( ) ;
196
+
197
+ let reader = io:: BufReader :: new ( File :: open ( file_path) . map_err ( |error| RadiusError :: MalformedDictionaryError { error } ) ?) ;
198
+ let lines = reader. lines ( )
199
+ . filter_map ( Result :: ok)
200
+ . filter ( |line| !line. is_empty ( ) )
201
+ . filter ( |line| !line. contains ( & COMMENT_PREFIX ) ) ;
202
+
203
+ for line in lines {
204
+ let parsed_line: Vec < & str > = line. split_whitespace ( ) . filter ( |& item| !item. is_empty ( ) ) . collect ( ) ;
205
+ match parsed_line[ 0 ] {
206
+ "ATTRIBUTE" => parse_attribute ( parsed_line, & vendor_name, attributes) ,
207
+ "VALUE" => parse_value ( parsed_line, & vendor_name, values) ,
208
+ "VENDOR" => parse_vendor ( parsed_line, vendors) ,
209
+ "BEGIN-VENDOR" => { vendor_name. insert_str ( 0 , parsed_line[ 1 ] ) } ,
210
+ "END-VENDOR" => { vendor_name. clear ( ) } ,
211
+ _ => continue
212
+ }
213
+ } ;
214
+
215
+ Ok ( ( ) )
216
+ }
217
+
201
218
fn parse_attribute ( parsed_line : Vec < & str > , vendor_name : & str , attributes : & mut Vec < DictionaryAttribute > ) {
202
219
if let Ok ( code) = parsed_line[ 2 ] . parse :: < u8 > ( ) {
203
220
attributes. push ( DictionaryAttribute {
@@ -341,4 +358,116 @@ mod tests {
341
358
let expected_dict = Dictionary { attributes, values, vendors } ;
342
359
assert_eq ! ( dict, expected_dict)
343
360
}
361
+
362
+ #[ test]
363
+ fn test_add_file ( ) {
364
+ let empty_dictionary_path = "./dict_examples/empty_test_dictionary_dict" ;
365
+ let dictionary_path = "./dict_examples/test_dictionary_dict" ;
366
+
367
+ let mut dict = Dictionary :: from_file ( empty_dictionary_path) . unwrap ( ) ;
368
+ dict. add_file ( dictionary_path) . unwrap ( ) ;
369
+
370
+ let mut attributes: Vec < DictionaryAttribute > = Vec :: new ( ) ;
371
+ attributes. push ( DictionaryAttribute {
372
+ name : "User-Name" . to_string ( ) ,
373
+ vendor_name : "" . to_string ( ) ,
374
+ code : 1 ,
375
+ code_type : Some ( SupportedAttributeTypes :: AsciiString )
376
+ } ) ;
377
+ attributes. push ( DictionaryAttribute {
378
+ name : "NAS-IP-Address" . to_string ( ) ,
379
+ vendor_name : "" . to_string ( ) ,
380
+ code : 4 ,
381
+ code_type : Some ( SupportedAttributeTypes :: IPv4Addr )
382
+ } ) ;
383
+ attributes. push ( DictionaryAttribute {
384
+ name : "NAS-Port-Id" . to_string ( ) ,
385
+ vendor_name : "" . to_string ( ) ,
386
+ code : 5 ,
387
+ code_type : Some ( SupportedAttributeTypes :: Integer )
388
+ } ) ;
389
+ attributes. push ( DictionaryAttribute {
390
+ name : "Framed-Protocol" . to_string ( ) ,
391
+ vendor_name : "" . to_string ( ) ,
392
+ code : 7 ,
393
+ code_type : Some ( SupportedAttributeTypes :: Integer )
394
+ } ) ;
395
+ attributes. push ( DictionaryAttribute {
396
+ name : "Chargeable-User-Identity" . to_string ( ) ,
397
+ vendor_name : "" . to_string ( ) ,
398
+ code : 89 ,
399
+ code_type : Some ( SupportedAttributeTypes :: ByteString )
400
+ } ) ;
401
+ attributes. push ( DictionaryAttribute {
402
+ name : "Delegated-IPv6-Prefix" . to_string ( ) ,
403
+ vendor_name : "" . to_string ( ) ,
404
+ code : 123 ,
405
+ code_type : Some ( SupportedAttributeTypes :: IPv6Prefix )
406
+ } ) ;
407
+ attributes. push ( DictionaryAttribute {
408
+ name : "MIP6-Feature-Vector" . to_string ( ) ,
409
+ vendor_name : "" . to_string ( ) ,
410
+ code : 124 ,
411
+ code_type : Some ( SupportedAttributeTypes :: Integer64 )
412
+ } ) ;
413
+ attributes. push ( DictionaryAttribute {
414
+ name : "Mobile-Node-Identifier" . to_string ( ) ,
415
+ vendor_name : "" . to_string ( ) ,
416
+ code : 145 ,
417
+ code_type : Some ( SupportedAttributeTypes :: ByteString )
418
+ } ) ;
419
+ attributes. push ( DictionaryAttribute {
420
+ name : "PMIP6-Home-Interface-ID" . to_string ( ) ,
421
+ vendor_name : "" . to_string ( ) ,
422
+ code : 153 ,
423
+ code_type : Some ( SupportedAttributeTypes :: InterfaceId )
424
+ } ) ;
425
+ attributes. push ( DictionaryAttribute {
426
+ name : "PMIP6-Home-IPv4-HoA" . to_string ( ) ,
427
+ vendor_name : "" . to_string ( ) ,
428
+ code : 155 ,
429
+ code_type : Some ( SupportedAttributeTypes :: IPv4Prefix )
430
+ } ) ;
431
+ attributes. push ( DictionaryAttribute {
432
+ name : "Somevendor-Name" . to_string ( ) ,
433
+ vendor_name : "Somevendor" . to_string ( ) ,
434
+ code : 1 ,
435
+ code_type : Some ( SupportedAttributeTypes :: AsciiString )
436
+ } ) ;
437
+ attributes. push ( DictionaryAttribute {
438
+ name : "Somevendor-Number" . to_string ( ) ,
439
+ vendor_name : "Somevendor" . to_string ( ) ,
440
+ code : 2 ,
441
+ code_type : Some ( SupportedAttributeTypes :: Integer )
442
+ } ) ;
443
+ attributes. push ( DictionaryAttribute {
444
+ name : "Class" . to_string ( ) ,
445
+ vendor_name : "" . to_string ( ) ,
446
+ code : 25 ,
447
+ code_type : Some ( SupportedAttributeTypes :: ByteString )
448
+ } ) ;
449
+
450
+ let mut values: Vec < DictionaryValue > = Vec :: new ( ) ;
451
+ values. push ( DictionaryValue {
452
+ attribute_name : "Framed-Protocol" . to_string ( ) ,
453
+ value_name : "PPP" . to_string ( ) ,
454
+ vendor_name : "" . to_string ( ) ,
455
+ value : "1" . to_string ( )
456
+ } ) ;
457
+ values. push ( DictionaryValue {
458
+ attribute_name : "Somevendor-Number" . to_string ( ) ,
459
+ value_name : "Two" . to_string ( ) ,
460
+ vendor_name : "Somevendor" . to_string ( ) ,
461
+ value : "2" . to_string ( )
462
+ } ) ;
463
+
464
+ let mut vendors: Vec < DictionaryVendor > = Vec :: new ( ) ;
465
+ vendors. push ( DictionaryVendor {
466
+ name : "Somevendor" . to_string ( ) ,
467
+ id : 10 ,
468
+ } ) ;
469
+
470
+ let expected_dict = Dictionary { attributes, values, vendors } ;
471
+ assert_eq ! ( dict, expected_dict)
472
+ }
344
473
}
0 commit comments