@@ -137,18 +137,23 @@ struct RawNodeDepKind {
137137 #[ serde( default ) ]
138138 #[ serde( deserialize_with = "deserialize_target" ) ]
139139 /// # Target.
140- target : bool ,
140+ target : Option < bool > ,
141141}
142142
143143impl RawNodeDepKind {
144144 /// # Into Flag.
145145 ///
146146 /// Convert the kind/target into the corresponding context flag used by
147147 /// our `Dependency` struct.
148+ ///
149+ /// Note that dev/impossible dependencies (without other uses) will get
150+ /// stripped automatically during deserialization.
148151 const fn as_flag ( self ) -> u8 {
149- if self . dev { Dependency :: FLAG_DEV }
150- else if self . target { Dependency :: FLAG_RUNTIME | Dependency :: FLAG_TARGET }
151- else { Dependency :: FLAG_RUNTIME | Dependency :: FLAG_ANY }
152+ match ( self . dev , self . target ) {
153+ ( true , _) | ( _, Some ( false ) ) => Dependency :: FLAG_DEV ,
154+ ( false , Some ( true ) ) => Dependency :: FLAG_RUNTIME | Dependency :: FLAG_TARGET ,
155+ ( false , None ) => Dependency :: FLAG_RUNTIME | Dependency :: FLAG_ANY ,
156+ }
152157 }
153158}
154159
@@ -243,8 +248,6 @@ fn cargo_exec<P: AsRef<Path>>(src: P, features: bool, target: Option<TargetTripl
243248/// # Default Dependency Kinds.
244249const fn default_depkinds ( ) -> u8 { Dependency :: FLAG_RUNTIME }
245250
246-
247-
248251#[ expect( clippy:: unnecessary_wraps, reason = "We don't control this signature." ) ]
249252/// # Deserialize: Dependency Kinds.
250253fn deserialize_depkinds < ' de , D > ( deserializer : D ) -> Result < u8 , D :: Error >
@@ -294,15 +297,20 @@ where D: Deserializer<'de> {
294297
295298#[ expect( clippy:: unnecessary_wraps, reason = "We don't control this signature." ) ]
296299/// # Deserialize: Target.
297- fn deserialize_target < ' de , D > ( deserializer : D ) -> Result < bool , D :: Error >
300+ ///
301+ /// Returns `None` if no cfg/target is specified, otherwise `Some(true)` if
302+ /// present.
303+ ///
304+ /// `Some(false)` is used for impossible values like "cfg(any())"; we'll strip
305+ /// them out subsequently.
306+ fn deserialize_target < ' de , D > ( deserializer : D ) -> Result < Option < bool > , D :: Error >
298307where D : Deserializer < ' de > {
299- Ok (
300- <Cow < str > >:: deserialize ( deserializer) . ok ( )
301- . map_or (
302- false ,
303- |o| ! o. trim ( ) . is_empty ( )
304- )
305- )
308+ Ok ( <Cow < str > >:: deserialize ( deserializer) . map_or (
309+ None ,
310+ |cond|
311+ if cond == "cfg(any())" { Some ( false ) }
312+ else { Some ( true ) }
313+ ) )
306314}
307315
308316/// # Parse Dependencies.
@@ -432,42 +440,49 @@ mod tests {
432440 let kind: RawNodeDepKind = serde_json:: from_str ( r#"{"kind": null, "target": null}"# )
433441 . expect ( "Failed to deserialize RawNodeDepKind" ) ;
434442 assert ! ( ! kind. dev) ;
435- assert ! ( ! kind. target) ;
443+ assert ! ( kind. target. is_none ( ) ) ;
436444 assert_eq ! ( kind. as_flag( ) , Dependency :: FLAG_RUNTIME | Dependency :: FLAG_ANY ) ;
437445
438446 // Build.
439447 let kind: RawNodeDepKind = serde_json:: from_str ( r#"{"kind": "build", "target": null}"# )
440448 . expect ( "Failed to deserialize RawNodeDepKind" ) ;
441449 assert ! ( ! kind. dev) ;
442- assert ! ( ! kind. target) ;
450+ assert ! ( kind. target. is_none ( ) ) ;
443451 assert_eq ! ( kind. as_flag( ) , Dependency :: FLAG_RUNTIME | Dependency :: FLAG_ANY ) ;
444452
445453 // Build and Target.
446454 let kind: RawNodeDepKind = serde_json:: from_str ( r#"{"kind": "build", "target": "cfg(unix)"}"# )
447455 . expect ( "Failed to deserialize RawNodeDepKind" ) ;
448456 assert ! ( ! kind. dev) ;
449- assert ! ( kind. target) ;
457+ assert_eq ! ( kind. target, Some ( true ) ) ;
450458 assert_eq ! ( kind. as_flag( ) , Dependency :: FLAG_RUNTIME | Dependency :: FLAG_TARGET ) ;
451459
452460 // Target.
453461 let kind: RawNodeDepKind = serde_json:: from_str ( r#"{"kind": null, "target": "cfg(target_os = \"hermit\")"}"# )
454462 . expect ( "Failed to deserialize RawNodeDepKind" ) ;
455463 assert ! ( ! kind. dev) ;
456- assert ! ( kind. target) ;
464+ assert_eq ! ( kind. target, Some ( true ) ) ;
457465 assert_eq ! ( kind. as_flag( ) , Dependency :: FLAG_RUNTIME | Dependency :: FLAG_TARGET ) ;
458466
467+ // Bullshit target (should be treated as dev).
468+ let kind: RawNodeDepKind = serde_json:: from_str ( r#"{"kind": null, "target": "cfg(any())"}"# )
469+ . expect ( "Failed to deserialize RawNodeDepKind" ) ;
470+ assert ! ( ! kind. dev) ;
471+ assert_eq ! ( kind. target, Some ( false ) ) ;
472+ assert_eq ! ( kind. as_flag( ) , Dependency :: FLAG_DEV ) ;
473+
459474 // Dev.
460475 let kind: RawNodeDepKind = serde_json:: from_str ( r#"{"kind": "dev", "target": null}"# )
461476 . expect ( "Failed to deserialize RawNodeDepKind" ) ;
462477 assert ! ( kind. dev) ;
463- assert ! ( ! kind. target) ;
478+ assert ! ( kind. target. is_none ( ) ) ;
464479 assert_eq ! ( kind. as_flag( ) , Dependency :: FLAG_DEV ) ;
465480
466- // Dev and target.
481+ // Dev and target (should be treated as dev) .
467482 let kind: RawNodeDepKind = serde_json:: from_str ( r#"{"kind": "dev", "target": "cfg(target_os = \"wasi\")"}"# )
468483 . expect ( "Failed to deserialize RawNodeDepKind" ) ;
469484 assert ! ( kind. dev) ;
470- assert ! ( kind. target) ;
471- assert_eq ! ( kind. as_flag( ) , Dependency :: FLAG_DEV ) ; // Dev takes priority.
485+ assert_eq ! ( kind. target, Some ( true ) ) ;
486+ assert_eq ! ( kind. as_flag( ) , Dependency :: FLAG_DEV ) ;
472487 }
473488}
0 commit comments