@@ -60,7 +60,7 @@ macro_rules! define_clients {
6060 format: $format: expr
6161 }
6262 ) ,* $( , ) ?) => {
63- #[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
63+ #[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
6464 pub enum PeerId {
6565 $( $variant( Id ) , ) *
6666 Unknown ( Id ) ,
@@ -356,7 +356,7 @@ define_clients! {
356356
357357impl Default for PeerId {
358358 /// Creates a new [PeerId] for the tortillas client using the
359- /// [Azureus](PeerIdFormat::Azureus) format
359+ /// [Azureus](PeerIdFormat::Azureus) format.
360360 fn default ( ) -> Self {
361361 // Fill entire array with random alphanumeric bytes
362362 let mut id = [ 0u8 ; 20 ] ;
@@ -370,18 +370,20 @@ impl Default for PeerId {
370370 id[ 0 ] = b'-' ;
371371 id[ 1 ..3 ] . copy_from_slice ( b"TO" ) ;
372372
373- let version = String :: from ( VERSION ) ;
374- let version = version. replace ( "." , "" ) ;
375- let version = if version. len ( ) < 4 {
376- version + "0"
377- } else {
378- version
379- } ;
380- let version = version. as_bytes ( ) ;
381-
382- let version_end = std:: cmp:: min ( 3 + version. len ( ) , 20 ) ;
383- id[ 3 ..version_end] . copy_from_slice ( & version[ ..version_end - 3 ] ) ;
384- id[ version_end] = b'-' ;
373+ // Extract digits only from version, ignoring prerelease/commit metadata
374+ // Extract core VERSION (before any non-digit/dot), keep only digits,
375+ // then pad/truncate to exactly 4 digits for Azureus "-XX####-".
376+ let core = VERSION
377+ . split ( |c : char | !c. is_ascii_digit ( ) && c != '.' )
378+ . next ( )
379+ . unwrap_or ( "0" ) ;
380+ let mut digits: String = core. chars ( ) . filter ( |c| c. is_ascii_digit ( ) ) . collect ( ) ;
381+ while digits. len ( ) < 4 {
382+ digits. push ( '0' ) ;
383+ }
384+ let digits4 = & digits[ ..4 ] ;
385+ id[ 3 ..7 ] . copy_from_slice ( digits4. as_bytes ( ) ) ;
386+ id[ 7 ] = b'-' ;
385387
386388 Self :: Tortillas ( id)
387389 }
@@ -407,19 +409,24 @@ impl From<Hash<20>> for PeerId {
407409impl fmt:: Display for PeerId {
408410 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
409411 if let Some ( version) = self . version ( ) {
410- write ! (
411- f,
412- "{} {} ({})" ,
413- self . client_name( ) ,
414- version,
415- hex:: encode( self . id( ) )
416- )
412+ write ! ( f, "{} {}" , self . client_name( ) , version)
417413 } else {
418- write ! ( f, "{} ({}) " , self . client_name( ) , hex :: encode ( self . id ( ) ) )
414+ write ! ( f, "{}" , self . client_name( ) )
419415 }
420416 }
421417}
422418
419+ impl fmt:: Debug for PeerId {
420+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
421+ write ! (
422+ f,
423+ "{} ({})" ,
424+ self . client_name( ) ,
425+ String :: from_utf8_lossy( self . id( ) )
426+ )
427+ }
428+ }
429+
423430impl FromStr for PeerId {
424431 type Err = std:: array:: TryFromSliceError ;
425432
@@ -444,14 +451,27 @@ mod tests {
444451 #[ test]
445452 fn test_parse_tortillas_peer_id ( ) {
446453 let peer = PeerId :: new ( ) ;
447- let correct_version = if VERSION . len ( ) <= 5 {
448- VERSION . to_owned ( ) + "0"
449- } else {
450- VERSION . to_owned ( )
451- } ;
454+ // Derive expected Azureus "A.B.CD" exactly like PeerId::default
455+ let core = VERSION
456+ . split ( |c : char | !c. is_ascii_digit ( ) && c != '.' )
457+ . next ( )
458+ . unwrap_or ( "0" ) ;
459+ let mut digits: String = core. chars ( ) . filter ( |c| c. is_ascii_digit ( ) ) . collect ( ) ;
460+ while digits. len ( ) < 4 {
461+ digits. push ( '0' ) ;
462+ }
463+ let b = digits. as_bytes ( ) ;
464+ let correct_version = format ! (
465+ "{}.{}.{}{}" ,
466+ b[ 0 ] as char , b[ 1 ] as char , b[ 2 ] as char , b[ 3 ] as char
467+ ) ;
452468
453469 assert_eq ! ( peer. client_name( ) , "Tortillas" ) ;
454470 assert_eq ! ( peer. version( ) , Some ( correct_version) ) ;
471+
472+ assert_eq ! ( peer. as_bytes( ) [ 0 ] , b'-' ) ;
473+ assert_eq ! ( & peer. as_bytes( ) [ 1 ..3 ] , b"TO" ) ;
474+ assert_eq ! ( peer. as_bytes( ) [ 7 ] , b'-' ) ;
455475 }
456476 #[ test]
457477 fn test_parse_webtorrent_peer_id ( ) {
0 commit comments