@@ -10,14 +10,18 @@ pub trait EnumVariantDowncast<VariantToken> {
1010}
1111
1212pub trait EnumVariantDowncastRef < VariantToken > {
13- type Target < ' target > where Self : ' target ;
13+ type Target < ' target >
14+ where
15+ Self : ' target ;
1416
1517 /// Returns a reference wrapper for the target field if the enum is the target variant
1618 fn downcast_ref ( & self ) -> Option < Self :: Target < ' _ > > ;
1719}
1820
1921pub trait EnumVariantDowncastMut < VariantToken > {
20- type Target < ' target > where Self : ' target ;
22+ type Target < ' target >
23+ where
24+ Self : ' target ;
2125
2226 /// Returns a mutable reference wrapper for the target field if the enum is the target variant
2327 fn downcast_mut ( & mut self ) -> Option < Self :: Target < ' _ > > ;
@@ -232,39 +236,46 @@ mod tests {
232236 name : "Alice" . to_string ( ) ,
233237 age : 30 ,
234238 } ;
235-
239+
236240 let location_data = StructVariantData :: Location {
237241 lat : 37.7749 ,
238242 lng : -122.4194 ,
239243 } ;
240-
244+
241245 let score_data = StructVariantData :: Score ( 95 ) ;
242-
246+
243247 // Test owned downcasting (struct variants only support owned downcasting for now)
244- if let Some ( person_fields) = person_data. clone ( ) . downcast :: < PersonVariant > ( ) {
248+ if let Some ( person_fields) =
249+ person_data. clone ( ) . downcast :: < PersonVariant > ( )
250+ {
245251 assert_eq ! ( person_fields. name, "Alice" ) ;
246252 assert_eq ! ( person_fields. age, 30 ) ;
247253 } else {
248254 panic ! ( "Failed to downcast person variant" ) ;
249255 }
250-
251- if let Some ( location_fields) = location_data. clone ( ) . downcast :: < LocationVariant > ( ) {
256+
257+ if let Some ( location_fields) =
258+ location_data. clone ( ) . downcast :: < LocationVariant > ( )
259+ {
252260 assert_eq ! ( location_fields. lat, 37.7749 ) ;
253261 assert_eq ! ( location_fields. lng, -122.4194 ) ;
254262 } else {
255263 panic ! ( "Failed to downcast location variant" ) ;
256264 }
257-
265+
258266 if let Some ( score) = score_data. downcast_ref :: < ScoreVariant > ( ) {
259267 assert_eq ! ( * score, 95 ) ;
260268 } else {
261269 panic ! ( "Failed to downcast score variant" ) ;
262270 }
263-
271+
264272 // Test From implementations with struct types
265- let person_struct = PersonFields { name : "Bob" . to_string ( ) , age : 25 } ;
273+ let person_struct = StructVariantDataPersonFields {
274+ name : "Bob" . to_string ( ) ,
275+ age : 25 ,
276+ } ;
266277 let data_from_struct = StructVariantData :: from ( person_struct) ;
267-
278+
268279 if let StructVariantData :: Person { name, age } = data_from_struct {
269280 assert_eq ! ( name, "Bob" ) ;
270281 assert_eq ! ( age, 25 ) ;
@@ -293,12 +304,12 @@ mod tests {
293304 name : "Alice" . to_string ( ) ,
294305 age : 30 ,
295306 } ;
296-
307+
297308 let location_data = StructVariantData :: Location {
298309 lat : 37.7749 ,
299310 lng : -122.4194 ,
300311 } ;
301-
312+
302313 let score_data = StructVariantData :: Score ( 95 ) ;
303314
304315 // Test basic matcher functionality for all variants
@@ -338,7 +349,7 @@ mod tests {
338349 name : "Alice" . to_string ( ) ,
339350 age : 30 ,
340351 } ;
341-
352+
342353 let location_data = StructVariantData :: Location {
343354 lat : 37.7749 ,
344355 lng : -122.4194 ,
@@ -367,15 +378,17 @@ mod tests {
367378 name : "Bob" . to_string ( ) ,
368379 age : 25 ,
369380 } ;
370-
381+
371382 let person_mut_ref = person_data_mut. downcast_mut :: < PersonVariant > ( ) ;
372383 if let Some ( person_fields_mut) = person_mut_ref {
373384 // We can modify the fields through the mutable references
374385 * person_fields_mut. age = 26 ;
375386 // Note: The original enum is not modified because we're working with a wrapper struct
376387 // This is expected behavior for this design
377388 } else {
378- panic ! ( "Mutable reference downcasting should work for struct variants now" ) ;
389+ panic ! (
390+ "Mutable reference downcasting should work for struct variants now"
391+ ) ;
379392 }
380393 }
381394
@@ -391,24 +404,25 @@ mod tests {
391404 assert ! ( location_ref. is_none( ) ) ;
392405
393406 let mut person_data_clone = person_data. clone ( ) ;
394- let location_mut_ref = person_data_clone. downcast_mut :: < LocationVariant > ( ) ;
407+ let location_mut_ref =
408+ person_data_clone. downcast_mut :: < LocationVariant > ( ) ;
395409 assert ! ( location_mut_ref. is_none( ) ) ;
396410 }
397411
398412 #[ test]
399413 fn test_new_trait_structure ( ) {
400414 // Test that the new three-trait structure works correctly
401415 let score_data = StructVariantData :: Score ( 95 ) ;
402-
416+
403417 // Test each trait separately
404418 // Owned downcasting should work for tuple variants
405419 let score_owned = score_data. clone ( ) . downcast :: < ScoreVariant > ( ) ;
406420 assert_eq ! ( score_owned, Some ( 95 ) ) ;
407-
421+
408422 // Reference downcasting should work for tuple variants
409423 let score_ref = score_data. downcast_ref :: < ScoreVariant > ( ) ;
410424 assert_eq ! ( score_ref, Some ( & 95 ) ) ;
411-
425+
412426 // Mutable reference downcasting should work for tuple variants
413427 let mut score_data_mut = StructVariantData :: Score ( 42 ) ;
414428 let score_mut_ref = score_data_mut. downcast_mut :: < ScoreVariant > ( ) ;
@@ -423,67 +437,122 @@ mod tests {
423437 age : 30 ,
424438 } ;
425439
426- // Test that downcast_ref returns PersonRef<'_>
427- let person_ref: Option < PersonRef < ' _ > > = person_data. downcast_ref :: < PersonVariant > ( ) ;
440+ // Test that downcast_ref returns StructVariantDataPersonRef<'_>
441+ let person_ref: Option < StructVariantDataPersonRef < ' _ > > =
442+ person_data. downcast_ref :: < PersonVariant > ( ) ;
428443 assert ! ( person_ref. is_some( ) ) ;
429444 let person_ref = person_ref. unwrap ( ) ;
430445 assert_eq ! ( person_ref. name, "Alice" ) ;
431446 assert_eq ! ( * person_ref. age, 30 ) ;
432447
433- // Test that downcast_mut returns PersonMut <'_>
448+ // Test that downcast_mut returns StructVariantDataPersonMut <'_>
434449 let mut person_data_mut = StructVariantData :: Person {
435450 name : "Bob" . to_string ( ) ,
436451 age : 25 ,
437452 } ;
438- let person_mut: Option < PersonMut < ' _ > > = person_data_mut. downcast_mut :: < PersonVariant > ( ) ;
453+ let person_mut: Option < StructVariantDataPersonMut < ' _ > > =
454+ person_data_mut. downcast_mut :: < PersonVariant > ( ) ;
439455 assert ! ( person_mut. is_some( ) ) ;
440456 let person_mut = person_mut. unwrap ( ) ;
441457 assert_eq ! ( person_mut. name, "Bob" ) ;
442458 * person_mut. age = 26 ; // Demonstrate mutable access
443459 assert_eq ! ( * person_mut. age, 26 ) ;
444460 }
445461
462+ #[ test]
463+ fn test_struct_from_conversions ( ) {
464+ // Test From conversions for struct reference types
465+ let person_data = StructVariantData :: Person {
466+ name : "Alice" . to_string ( ) ,
467+ age : 30 ,
468+ } ;
469+
470+ // Test Ref -> Fields conversion
471+ if let Some ( person_ref) = person_data. downcast_ref :: < PersonVariant > ( ) {
472+ let person_fields: StructVariantDataPersonFields =
473+ person_ref. into ( ) ;
474+ assert_eq ! ( person_fields. name, "Alice" ) ;
475+ assert_eq ! ( person_fields. age, 30 ) ;
476+ } else {
477+ panic ! ( "Failed to downcast to PersonRef" ) ;
478+ }
479+
480+ // Test Mut -> Fields conversion
481+ let mut person_data_mut = StructVariantData :: Person {
482+ name : "Bob" . to_string ( ) ,
483+ age : 25 ,
484+ } ;
485+
486+ if let Some ( person_mut) =
487+ person_data_mut. downcast_mut :: < PersonVariant > ( )
488+ {
489+ let person_fields: StructVariantDataPersonFields =
490+ person_mut. into ( ) ;
491+ assert_eq ! ( person_fields. name, "Bob" ) ;
492+ assert_eq ! ( person_fields. age, 25 ) ;
493+ } else {
494+ panic ! ( "Failed to downcast to PersonMut" ) ;
495+ }
496+
497+ // Test reference-to-reference conversion
498+ let location_data = StructVariantData :: Location {
499+ lat : 37.7749 ,
500+ lng : -122.4194 ,
501+ } ;
502+
503+ if let Some ( location_ref) =
504+ location_data. downcast_ref :: < LocationVariant > ( )
505+ {
506+ let location_fields: StructVariantDataLocationFields =
507+ ( & location_ref) . into ( ) ;
508+ assert_eq ! ( location_fields. lat, 37.7749 ) ;
509+ assert_eq ! ( location_fields. lng, -122.4194 ) ;
510+ } else {
511+ panic ! ( "Failed to downcast to LocationRef" ) ;
512+ }
513+ }
514+
446515 #[ test]
447516 fn test_complete_reference_downcasting_functionality ( ) {
448517 // Comprehensive test demonstrating the complete functionality
449-
518+
450519 // Test struct variants with reference downcasting
451520 let person = StructVariantData :: Person {
452521 name : "Alice" . to_string ( ) ,
453522 age : 30 ,
454523 } ;
455-
524+
456525 // Test owned downcasting (returns PersonFields)
457526 let person_owned = person. clone ( ) . downcast :: < PersonVariant > ( ) . unwrap ( ) ;
458527 assert_eq ! ( person_owned. name, "Alice" ) ;
459528 assert_eq ! ( person_owned. age, 30 ) ;
460-
529+
461530 // Test reference downcasting (returns PersonRef<'_>)
462531 let person_ref = person. downcast_ref :: < PersonVariant > ( ) . unwrap ( ) ;
463532 assert_eq ! ( person_ref. name, "Alice" ) ;
464533 assert_eq ! ( * person_ref. age, 30 ) ;
465-
534+
466535 // Test mutable reference downcasting (returns PersonMut<'_>)
467536 let mut person_mut = StructVariantData :: Person {
468537 name : "Bob" . to_string ( ) ,
469538 age : 25 ,
470539 } ;
471- let person_mut_ref = person_mut. downcast_mut :: < PersonVariant > ( ) . unwrap ( ) ;
540+ let person_mut_ref =
541+ person_mut. downcast_mut :: < PersonVariant > ( ) . unwrap ( ) ;
472542 assert_eq ! ( person_mut_ref. name, "Bob" ) ;
473543 * person_mut_ref. age = 26 ;
474544 assert_eq ! ( * person_mut_ref. age, 26 ) ;
475-
545+
476546 // Test tuple variants still work
477547 let score = StructVariantData :: Score ( 95 ) ;
478548 assert_eq ! ( score. clone( ) . downcast:: <ScoreVariant >( ) , Some ( 95 ) ) ;
479549 assert_eq ! ( score. downcast_ref:: <ScoreVariant >( ) , Some ( & 95 ) ) ;
480-
550+
481551 let mut score_mut = StructVariantData :: Score ( 42 ) ;
482552 assert_eq ! ( score_mut. downcast_mut:: <ScoreVariant >( ) , Some ( & mut 42 ) ) ;
483-
553+
484554 // Test wrong type downcasting returns None
485555 assert ! ( person. downcast_ref:: <LocationVariant >( ) . is_none( ) ) ;
486556 assert ! ( person. downcast_ref:: <ScoreVariant >( ) . is_none( ) ) ;
487557 }
488-
489558}
0 commit comments