@@ -161,13 +161,29 @@ impl PartitionTable {
161161 . ok_or_else ( || anyhow:: anyhow!( "Missing partition for index {partno}" ) ) ?;
162162 Ok ( r)
163163 }
164+
165+ /// Find the partition with the given type UUID (case-insensitive).
166+ ///
167+ /// Partition type UUIDs are compared case-insensitively per the GPT specification,
168+ /// as different tools may report them in different cases.
169+ pub fn find_partition_of_type ( & self , uuid : & str ) -> Option < & Partition > {
170+ self . partitions . iter ( ) . find ( |p| p. parttype_matches ( uuid) )
171+ }
164172}
165173
166174impl Partition {
167175 #[ allow( dead_code) ]
168176 pub fn path ( & self ) -> & Utf8Path {
169177 self . node . as_str ( ) . into ( )
170178 }
179+
180+ /// Check if this partition's type matches the given UUID (case-insensitive).
181+ ///
182+ /// Partition type UUIDs are compared case-insensitively per the GPT specification,
183+ /// as different tools may report them in different cases.
184+ pub fn parttype_matches ( & self , uuid : & str ) -> bool {
185+ self . parttype . eq_ignore_ascii_case ( uuid)
186+ }
171187}
172188
173189#[ context( "Listing partitions of {dev}" ) ]
@@ -505,4 +521,85 @@ mod test {
505521 ) ;
506522 Ok ( ( ) )
507523 }
524+
525+ #[ test]
526+ fn test_parttype_matches ( ) {
527+ let partition = Partition {
528+ node : "/dev/loop0p1" . to_string ( ) ,
529+ start : 2048 ,
530+ size : 8192 ,
531+ parttype : "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" . to_string ( ) , // lowercase ESP UUID
532+ uuid : Some ( "58A4C5F0-BD12-424C-B563-195AC65A25DD" . to_string ( ) ) ,
533+ name : Some ( "EFI System" . to_string ( ) ) ,
534+ } ;
535+
536+ // Test exact match (lowercase)
537+ assert ! ( partition. parttype_matches( "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" ) ) ;
538+
539+ // Test case-insensitive match (uppercase)
540+ assert ! ( partition. parttype_matches( "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" ) ) ;
541+
542+ // Test case-insensitive match (mixed case)
543+ assert ! ( partition. parttype_matches( "C12a7328-F81f-11d2-Ba4b-00a0C93ec93b" ) ) ;
544+
545+ // Test non-match
546+ assert ! ( !partition. parttype_matches( "0FC63DAF-8483-4772-8E79-3D69D8477DE4" ) ) ;
547+ }
548+
549+ #[ test]
550+ fn test_find_partition_of_type ( ) -> Result < ( ) > {
551+ let fixture = indoc:: indoc! { r#"
552+ {
553+ "partitiontable": {
554+ "label": "gpt",
555+ "id": "A67AA901-2C72-4818-B098-7F1CAC127279",
556+ "device": "/dev/loop0",
557+ "unit": "sectors",
558+ "firstlba": 34,
559+ "lastlba": 20971486,
560+ "sectorsize": 512,
561+ "partitions": [
562+ {
563+ "node": "/dev/loop0p1",
564+ "start": 2048,
565+ "size": 8192,
566+ "type": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B",
567+ "uuid": "58A4C5F0-BD12-424C-B563-195AC65A25DD",
568+ "name": "EFI System"
569+ },{
570+ "node": "/dev/loop0p2",
571+ "start": 10240,
572+ "size": 20961247,
573+ "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
574+ "uuid": "F51ABB0D-DA16-4A21-83CB-37F4C805AAA0",
575+ "name": "root"
576+ }
577+ ]
578+ }
579+ }
580+ "# } ;
581+ let table: SfDiskOutput = serde_json:: from_str ( fixture) . unwrap ( ) ;
582+
583+ // Find ESP partition using lowercase UUID (should match uppercase in fixture)
584+ let esp = table
585+ . partitiontable
586+ . find_partition_of_type ( "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" ) ;
587+ assert ! ( esp. is_some( ) ) ;
588+ assert_eq ! ( esp. unwrap( ) . node, "/dev/loop0p1" ) ;
589+
590+ // Find root partition using uppercase UUID (should match case-insensitively)
591+ let root = table
592+ . partitiontable
593+ . find_partition_of_type ( "0fc63daf-8483-4772-8e79-3d69d8477de4" ) ;
594+ assert ! ( root. is_some( ) ) ;
595+ assert_eq ! ( root. unwrap( ) . node, "/dev/loop0p2" ) ;
596+
597+ // Try to find non-existent partition type
598+ let nonexistent = table
599+ . partitiontable
600+ . find_partition_of_type ( "00000000-0000-0000-0000-000000000000" ) ;
601+ assert ! ( nonexistent. is_none( ) ) ;
602+
603+ Ok ( ( ) )
604+ }
508605}
0 commit comments