@@ -89,68 +89,70 @@ pub struct IndexEntry {
89
89
// a CString which is owned by the function. To make the pointer to the CString
90
90
// valid during usage of raw::git_index_entry, we supply the index entry in a
91
91
// 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 > ,
95
95
) -> 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 ;
101
119
} else {
102
- Ok ( None )
120
+ flags |= raw :: GIT_INDEX_ENTRY_NAMEMASK ;
103
121
}
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
+ } )
147
144
}
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
+ }
154
156
155
157
cb ( & raw_entry_ptrs)
156
158
}
0 commit comments