@@ -211,26 +211,29 @@ impl<'a> std::fmt::Display for PrettyRef<'a> {
211211
212212/// Information to find the source package and patch files.
213213#[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
214- pub struct PatchInfo {
215- /// Name of the package to be patched.
216- name : String ,
217- /// Verision of the package to be patched.
218- version : String ,
219- /// Absolute paths to patch files.
220- ///
221- /// These are absolute to ensure Cargo can locate them in the patching phase.
222- patches : Vec < PathBuf > ,
214+ pub enum PatchInfo {
215+ /// The package to be patched is known and finalized.
216+ Resolved {
217+ /// Name and version of the package to be patched.
218+ name : String ,
219+ /// Version of the package to be patched.
220+ version : String ,
221+ /// Absolute paths to patch files.
222+ ///
223+ /// These are absolute to ensure Cargo can locate them in the patching phase.
224+ patches : Vec < PathBuf > ,
225+ } ,
226+ /// The package to be patched hasn't yet be resolved. Usually after a few
227+ /// times of dependecy resolution, this will become [`PatchInfo::Resolved`].
228+ Deferred {
229+ /// Absolute paths to patch files.
230+ ///
231+ /// These are absolute to ensure Cargo can locate them in the patching phase.
232+ patches : Vec < PathBuf > ,
233+ } ,
223234}
224235
225236impl PatchInfo {
226- pub fn new ( name : String , version : String , patches : Vec < PathBuf > ) -> PatchInfo {
227- PatchInfo {
228- name,
229- version,
230- patches,
231- }
232- }
233-
234237 /// Collects patch information from query string.
235238 ///
236239 /// * `name` --- Package name
@@ -256,24 +259,34 @@ impl PatchInfo {
256259 if patches. is_empty ( ) {
257260 return Err ( PatchInfoError ( "path" ) ) ;
258261 }
259- Ok ( PatchInfo :: new ( name, version, patches) )
262+ Ok ( PatchInfo :: Resolved {
263+ name,
264+ version,
265+ patches,
266+ } )
260267 }
261268
262269 /// As a URL query string.
263270 pub fn as_query ( & self ) -> PatchInfoQuery < ' _ > {
264271 PatchInfoQuery ( self )
265272 }
266273
267- pub fn name ( & self ) -> & str {
268- self . name . as_str ( )
269- }
270-
271- pub fn version ( & self ) -> & str {
272- self . version . as_str ( )
274+ pub fn finalize ( self , name : String , version : String ) -> Self {
275+ match self {
276+ PatchInfo :: Deferred { patches } => PatchInfo :: Resolved {
277+ name,
278+ version,
279+ patches,
280+ } ,
281+ _ => panic ! ( "patch info has already finalized: {self:?}" ) ,
282+ }
273283 }
274284
275285 pub fn patches ( & self ) -> & [ PathBuf ] {
276- self . patches . as_slice ( )
286+ match self {
287+ PatchInfo :: Resolved { patches, .. } => patches. as_slice ( ) ,
288+ PatchInfo :: Deferred { patches } => patches. as_slice ( ) ,
289+ }
277290 }
278291}
279292
@@ -282,22 +295,38 @@ pub struct PatchInfoQuery<'a>(&'a PatchInfo);
282295
283296impl < ' a > std:: fmt:: Display for PatchInfoQuery < ' a > {
284297 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
285- write ! ( f, "name=" ) ?;
286- for value in url:: form_urlencoded:: byte_serialize ( self . 0 . name . as_bytes ( ) ) {
287- write ! ( f, "{value}" ) ?;
288- }
289- write ! ( f, "&version=" ) ?;
290- for value in url:: form_urlencoded:: byte_serialize ( self . 0 . version . as_bytes ( ) ) {
291- write ! ( f, "{value}" ) ?;
298+ match self . 0 {
299+ PatchInfo :: Resolved {
300+ name,
301+ version,
302+ patches,
303+ } => {
304+ f. write_str ( "name=" ) ?;
305+ for value in url:: form_urlencoded:: byte_serialize ( name. as_bytes ( ) ) {
306+ write ! ( f, "{value}" ) ?;
307+ }
308+ f. write_str ( "&version=" ) ?;
309+ for value in url:: form_urlencoded:: byte_serialize ( version. as_bytes ( ) ) {
310+ write ! ( f, "{value}" ) ?;
311+ }
312+ if !patches. is_empty ( ) {
313+ f. write_str ( "&" ) ?;
314+ }
315+ }
316+ _ => { }
292317 }
293- for path in & self . 0 . patches {
294- write ! ( f, "&patch=" ) ?;
318+
319+ let mut patches = self . 0 . patches ( ) . iter ( ) . peekable ( ) ;
320+ while let Some ( path) = patches. next ( ) {
321+ f. write_str ( "patch=" ) ?;
295322 let path = path. to_str ( ) . expect ( "utf8 patch" ) . replace ( "\\ " , "/" ) ;
296323 for value in url:: form_urlencoded:: byte_serialize ( path. as_bytes ( ) ) {
297324 write ! ( f, "{value}" ) ?;
298325 }
326+ if patches. peek ( ) . is_some ( ) {
327+ f. write_str ( "&" ) ?
328+ }
299329 }
300-
301330 Ok ( ( ) )
302331 }
303332}
0 commit comments