@@ -596,12 +596,21 @@ impl<'a> Decoder<'a> {
596596 Some ( result)
597597 }
598598 ( Some ( _) , None ) => {
599- // This can only happen if there is an uneven number of elements.
600- * last_string = None ;
601- Some ( Err ( Error :: new (
602- ErrorKind :: Parsing ,
603- "uneven number of IPLS strings" ,
604- ) ) )
599+ // This can only happen if there is an uneven number of elements. For
600+ // compatibility, we assume that the missing value is an empty string instead of
601+ // erroring out and failing to parse the entire tag.
602+ //
603+ // This is in line with what the Python mutagen library does. See this issue for
604+ // details:
605+ // - <https://github.com/polyfloyd/rust-id3/issues/147>
606+ let first = last_string. take ( ) . expect ( "option must be some" ) ;
607+ let result = first. map ( |involvement| {
608+ Some ( InvolvedPeopleListItem {
609+ involvement,
610+ involvee : String :: new ( ) ,
611+ } )
612+ } ) ;
613+ Some ( result)
605614 }
606615 ( None , None ) => None ,
607616 } )
@@ -1711,7 +1720,28 @@ mod tests {
17111720 data. extend ( bytes_for_encoding ( "other involvement" , * encoding) . into_iter ( ) ) ;
17121721 data. extend ( delim_for_encoding ( * encoding) . into_iter ( ) ) ;
17131722 // involveee missing here
1714- assert ! ( decode( frame_id, version, & data[ ..] ) . is_err( ) ) ;
1723+
1724+ let content = frame:: InvolvedPeopleList {
1725+ items : vec ! [
1726+ InvolvedPeopleListItem {
1727+ involvement: "involvement" . to_string( ) ,
1728+ involvee: "involvee" . to_string( ) ,
1729+ } ,
1730+ InvolvedPeopleListItem {
1731+ involvement: "other involvement" . to_string( ) ,
1732+ // Assume empty string if value is missing
1733+ involvee: "" . to_string( ) ,
1734+ } ,
1735+ ] ,
1736+ } ;
1737+ assert_eq ! (
1738+ * decode( frame_id, version, & data[ ..] )
1739+ . unwrap( )
1740+ . 0
1741+ . involved_people_list( )
1742+ . unwrap( ) ,
1743+ content
1744+ ) ;
17151745 }
17161746 }
17171747
0 commit comments