@@ -89,68 +89,70 @@ pub struct IndexEntry {
8989// a CString which is owned by the function. To make the pointer to the CString
9090// valid during usage of raw::git_index_entry, we supply the index entry in a
9191// callback where pointers to the CString are valid.
92- fn try_raw_entries (
93- entries : & [ Option < & IndexEntry > ] ,
94- cb : impl FnOnce ( & [ * const raw:: git_index_entry ] ) -> Result < ( ) , Error > ,
92+ fn try_raw_entries < const N : usize > (
93+ entries : & [ Option < & IndexEntry > ; N ] ,
94+ cb : impl FnOnce ( & [ * const raw:: git_index_entry ; N ] ) -> Result < ( ) , Error > ,
9595) -> Result < ( ) , Error > {
96- let paths = entries
97- . iter ( )
98- . map ( |entry| {
99- if let Some ( entry) = entry {
100- CString :: new ( & entry. path [ ..] ) . map ( |ok| Some ( ok) )
96+ let mut paths: [ Option < CString > ; N ] = unsafe {
97+ std:: mem:: MaybeUninit :: uninit ( ) . assume_init ( )
98+ } ;
99+ for ( idx, entry) in entries. iter ( ) . enumerate ( ) {
100+ paths[ idx] = if let Some ( entry) = entry {
101+ Some ( CString :: new ( & entry. path [ ..] ) ?)
102+ } else {
103+ None
104+ }
105+ }
106+
107+ let mut raw_entries: [ Option < raw:: git_index_entry > ; N ] = unsafe {
108+ std:: mem:: MaybeUninit :: uninit ( ) . assume_init ( )
109+ } ;
110+ for ( idx, ( entry, path) ) in entries. iter ( ) . zip ( & paths) . enumerate ( ) {
111+ raw_entries[ idx] = if let Some ( entry) = entry {
112+ // libgit2 encodes the length of the path in the lower bits of the
113+ // `flags` entry, so mask those out and recalculate here to ensure we
114+ // don't corrupt anything.
115+ let mut flags = entry. flags & !raw:: GIT_INDEX_ENTRY_NAMEMASK ;
116+
117+ if entry. path . len ( ) < raw:: GIT_INDEX_ENTRY_NAMEMASK as usize {
118+ flags |= entry. path . len ( ) as u16 ;
101119 } else {
102- Ok ( None )
120+ flags |= raw :: GIT_INDEX_ENTRY_NAMEMASK ;
103121 }
104- } )
105- . collect :: < Result < Vec < Option < CString > > , std:: ffi:: NulError > > ( ) ?;
106-
107- let raw_entries = entries
108- . iter ( )
109- . zip ( & paths)
110- . map ( |( entry, path) | {
111- if let Some ( entry) = entry {
112- // libgit2 encodes the length of the path in the lower bits of the
113- // `flags` entry, so mask those out and recalculate here to ensure we
114- // don't corrupt anything.
115- let mut flags = entry. flags & !raw:: GIT_INDEX_ENTRY_NAMEMASK ;
116-
117- if entry. path . len ( ) < raw:: GIT_INDEX_ENTRY_NAMEMASK as usize {
118- flags |= entry. path . len ( ) as u16 ;
119- } else {
120- flags |= raw:: GIT_INDEX_ENTRY_NAMEMASK ;
121- }
122-
123- unsafe {
124- Some ( raw:: git_index_entry {
125- dev : entry. dev ,
126- ino : entry. ino ,
127- mode : entry. mode ,
128- uid : entry. uid ,
129- gid : entry. gid ,
130- file_size : entry. file_size ,
131- id : * entry. id . raw ( ) ,
132- flags,
133- flags_extended : entry. flags_extended ,
134- path : path. as_ref ( ) . unwrap ( ) . as_ptr ( ) ,
135- mtime : raw:: git_index_time {
136- seconds : entry. mtime . seconds ( ) ,
137- nanoseconds : entry. mtime . nanoseconds ( ) ,
138- } ,
139- ctime : raw:: git_index_time {
140- seconds : entry. ctime . seconds ( ) ,
141- nanoseconds : entry. ctime . nanoseconds ( ) ,
142- } ,
143- } )
144- }
145- } else {
146- None
122+
123+ unsafe {
124+ Some ( raw:: git_index_entry {
125+ dev : entry. dev ,
126+ ino : entry. ino ,
127+ mode : entry. mode ,
128+ uid : entry. uid ,
129+ gid : entry. gid ,
130+ file_size : entry. file_size ,
131+ id : * entry. id . raw ( ) ,
132+ flags,
133+ flags_extended : entry. flags_extended ,
134+ path : path. as_ref ( ) . unwrap ( ) . as_ptr ( ) ,
135+ mtime : raw:: git_index_time {
136+ seconds : entry. mtime . seconds ( ) ,
137+ nanoseconds : entry. mtime . nanoseconds ( ) ,
138+ } ,
139+ ctime : raw:: git_index_time {
140+ seconds : entry. ctime . seconds ( ) ,
141+ nanoseconds : entry. ctime . nanoseconds ( ) ,
142+ } ,
143+ } )
147144 }
148- } )
149- . collect :: < Vec < _ > > ( ) ;
150- let raw_entry_ptrs = raw_entries
151- . iter ( )
152- . map ( |opt| opt. as_ref ( ) . map_or_else ( std:: ptr:: null, |ptr| ptr) )
153- . collect :: < Vec < _ > > ( ) ;
145+ } else {
146+ None
147+ }
148+ }
149+
150+ let mut raw_entry_ptrs: [ * const raw:: git_index_entry ; N ] = unsafe {
151+ std:: mem:: MaybeUninit :: uninit ( ) . assume_init ( )
152+ } ;
153+ for ( idx, entry) in raw_entries. iter ( ) . enumerate ( ) {
154+ raw_entry_ptrs[ idx] = entry. as_ref ( ) . map_or_else ( std:: ptr:: null, |ptr| ptr) ;
155+ }
154156
155157 cb ( & raw_entry_ptrs)
156158}
0 commit comments