@@ -6,7 +6,6 @@ use crate::message::{Config, Message};
66use crate :: parsed_message:: { GarbledReason , InvalidReason , ParsedMessage } ;
77use crate :: parts:: { Body , Header , RepeatingGroup , Trailer } ;
88use crate :: tags:: { BEGIN_STRING , BODY_LENGTH , CHECK_SUM , MSG_TYPE } ;
9- use anyhow:: anyhow;
109use hotfix_dictionary:: { Dictionary , LayoutItem , LayoutItemKind , TagU32 } ;
1110use std:: collections:: { HashMap , HashSet } ;
1211
@@ -32,7 +31,7 @@ pub struct MessageBuilder {
3231}
3332
3433impl MessageBuilder {
35- pub fn new ( dict : Dictionary , config : Config ) -> anyhow :: Result < Self > {
34+ pub fn new ( dict : Dictionary , config : Config ) -> ParserResult < Self > {
3635 let header_tags = Self :: get_tags_for_component ( & dict, "StandardHeader" ) ?;
3736 let trailer_tags = Self :: get_tags_for_component ( & dict, "StandardTrailer" ) ?;
3837 let message_definitions = build_message_specifications ( & dict) ?;
@@ -66,7 +65,8 @@ impl MessageBuilder {
6665 }
6766 } ;
6867
69- let msg_type = header. get :: < & str > ( MSG_TYPE ) . unwrap ( ) ; // we know this is valid at this point as we have already verified the integrity of the header
68+ #[ allow( clippy:: expect_used) ]
69+ let msg_type = header. get :: < & str > ( MSG_TYPE ) . expect ( "we know this is valid at this point as we have already verified the integrity of the header" ) ;
7070 let ( body, next) = match self . build_body ( msg_type, & mut parser, next) {
7171 Ok ( ( body, field) ) => ( body, field) ,
7272 Err ( err) => {
@@ -174,9 +174,10 @@ impl MessageBuilder {
174174 } else {
175175 // check the message type once all other header fields have been parsed
176176 // we delay it until after parsing so our rejection has access to fields like the sequence number
177+ #[ allow( clippy:: expect_used) ]
177178 let msg_type = header
178179 . get :: < & str > ( MSG_TYPE )
179- . expect ( "this should never fail as we've verified the integrity of the header" ) ;
180+ . expect ( "this never fails as we've verified the integrity of the header" ) ;
180181 if self . dict . message_by_msgtype ( msg_type) . is_none ( ) {
181182 return Err ( ParserError :: InvalidMsgType ( msg_type. to_string ( ) ) ) ;
182183 }
@@ -197,15 +198,17 @@ impl MessageBuilder {
197198 let mut field = next_field;
198199
199200 while message_def. contains_tag ( field. tag ) {
200- let tag = field. tag . get ( ) ;
201+ let tag = field. tag ;
201202 body. store_field ( field) ;
202203
203204 // check if it's the start of a group and parse the group as needed
204- let field_def = self . get_dict_field_by_tag ( tag) ?;
205- match message_def. get_group ( TagU32 :: new ( tag) . unwrap ( ) ) {
205+ let field_def = self . get_dict_field_by_tag ( tag. get ( ) ) ?;
206+ match message_def. get_group ( tag) {
206207 Some ( group_def) => {
207208 let ( groups, next) = Self :: parse_groups ( parser, group_def, field_def. tag ( ) ) ?;
208- body. set_groups ( groups) ;
209+ #[ allow( clippy:: expect_used) ]
210+ body. set_groups ( groups)
211+ . expect ( "groups are guaranteed to be valid at this point" ) ;
209212 field = next;
210213 }
211214 None => {
@@ -259,7 +262,10 @@ impl MessageBuilder {
259262 {
260263 let ( groups, next) =
261264 Self :: parse_groups ( parser, nested_group_def, current_tag) ?;
262- group. set_groups ( groups) ;
265+ #[ allow( clippy:: expect_used) ]
266+ group
267+ . set_groups ( groups)
268+ . expect ( "groups are guaranteed to be valid at this point" ) ;
263269 next
264270 } else {
265271 parser
@@ -316,11 +322,11 @@ impl MessageBuilder {
316322 fn get_tags_for_component (
317323 dict : & Dictionary ,
318324 component_name : & str ,
319- ) -> anyhow :: Result < HashSet < TagU32 > > {
325+ ) -> ParserResult < HashSet < TagU32 > > {
320326 let mut tags = HashSet :: new ( ) ;
321327 let component = dict
322328 . component_by_name ( component_name)
323- . ok_or ( ParserError :: InvalidComponent ( component_name. to_string ( ) ) ) ?;
329+ . ok_or_else ( || ParserError :: InvalidComponent ( component_name. to_string ( ) ) ) ?;
324330 for item in component. items ( ) {
325331 if let LayoutItemKind :: Field ( field) = item. kind ( ) {
326332 tags. insert ( field. tag ( ) ) ;
@@ -425,6 +431,7 @@ impl GroupSpecification {
425431 }
426432
427433 pub fn delimiter_tag ( & self ) -> TagU32 {
434+ #[ allow( clippy:: expect_used) ]
428435 self . fields
429436 . first ( )
430437 . expect ( "groups always have at least one field" )
@@ -457,7 +464,7 @@ impl MessageSpecification {
457464
458465fn build_message_specifications (
459466 dict : & Dictionary ,
460- ) -> anyhow :: Result < HashMap < String , MessageSpecification > > {
467+ ) -> ParserResult < HashMap < String , MessageSpecification > > {
461468 let mut definitions = HashMap :: new ( ) ;
462469
463470 for message in dict. messages ( ) {
@@ -467,26 +474,25 @@ fn build_message_specifications(
467474 . flatten ( )
468475 . collect ( ) ;
469476
470- let message_def = MessageSpecification {
471- fields,
472- groups : message. layout ( ) . fold ( HashMap :: new ( ) , |mut acc, item| {
473- acc. extend ( extract_groups ( dict, item) . unwrap ( ) ) ;
474- acc
475- } ) ,
476- } ;
477+ let mut groups = HashMap :: new ( ) ;
478+ for item in message. layout ( ) {
479+ groups. extend ( extract_groups ( dict, item) ?) ;
480+ }
481+
482+ let message_def = MessageSpecification { fields, groups } ;
477483 definitions. insert ( message. msg_type ( ) . to_string ( ) , message_def) ;
478484 }
479485
480486 Ok ( definitions)
481487}
482488
483- fn extract_fields ( dict : & Dictionary , item : LayoutItem ) -> anyhow :: Result < Vec < FieldSpecification > > {
489+ fn extract_fields ( dict : & Dictionary , item : LayoutItem ) -> ParserResult < Vec < FieldSpecification > > {
484490 let is_required = item. required ( ) ;
485491 let fields = match item. kind ( ) {
486492 LayoutItemKind :: Component ( c) => {
487493 let component = dict
488494 . component_by_name ( c. name ( ) )
489- . ok_or_else ( || anyhow ! ( "missing component" ) ) ?;
495+ . ok_or_else ( || ParserError :: InvalidComponent ( c . name ( ) . to_string ( ) ) ) ?;
490496 component
491497 . items ( )
492498 . flat_map ( |i| extract_fields ( dict, i) )
@@ -509,18 +515,22 @@ fn extract_fields(dict: &Dictionary, item: LayoutItem) -> anyhow::Result<Vec<Fie
509515fn extract_groups (
510516 dict : & Dictionary ,
511517 item : LayoutItem ,
512- ) -> anyhow :: Result < HashMap < TagU32 , GroupSpecification > > {
518+ ) -> ParserResult < HashMap < TagU32 , GroupSpecification > > {
513519 let mut groups = HashMap :: new ( ) ;
514520 match item. kind ( ) {
515521 LayoutItemKind :: Component ( c) => {
516522 let component = dict
517523 . component_by_name ( c. name ( ) )
518- . ok_or_else ( || anyhow ! ( "missing component" ) ) ?;
519- component. items ( ) . for_each ( |i| {
520- groups. extend ( extract_groups ( dict, i) . unwrap ( ) ) ;
521- } )
524+ . ok_or_else ( || ParserError :: InvalidComponent ( c . name ( ) . to_string ( ) ) ) ?;
525+ for i in component. items ( ) {
526+ groups. extend ( extract_groups ( dict, i) ? ) ;
527+ }
522528 }
523529 LayoutItemKind :: Group ( field, items) => {
530+ let mut nested_groups = HashMap :: new ( ) ;
531+ for i in items. iter ( ) {
532+ nested_groups. extend ( extract_groups ( dict, i. clone ( ) ) ?) ;
533+ }
524534 groups. insert (
525535 field. tag ( ) ,
526536 GroupSpecification {
@@ -530,10 +540,7 @@ fn extract_groups(
530540 . flat_map ( |i| extract_fields ( dict, i. clone ( ) ) )
531541 . flatten ( )
532542 . collect ( ) ,
533- nested_groups : items. iter ( ) . fold ( HashMap :: new ( ) , |mut acc, i| {
534- acc. extend ( extract_groups ( dict, i. clone ( ) ) . unwrap ( ) ) ;
535- acc
536- } ) ,
543+ nested_groups,
537544 } ,
538545 ) ;
539546 }
0 commit comments