Repository: oli-obk/cargo_metadata
Pull request #130 (2020-10-05 17:52:57)

Add workspace metadata field.
This adds support for the new "metadata" field found at the workspace level.

Also, this eliminates the workspace and project metadata fields from being serialized if they are null.


Patch:
diff --git a/src/lib.rs b/src/lib.rs
index b7a8390..eb2e151 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -120,6 +120,14 @@ impl std::fmt::Display for PackageId {
     }
 }
 
+// Helpers for default metadata fields
+fn is_null(value: &serde_json::Value) -> bool {
+    match value {
+        serde_json::Value::Null => true,
+        _ => false,
+    }
+}
+
 #[derive(Clone, Serialize, Deserialize, Debug)]
 /// Starting point for metadata returned by `cargo metadata`
 pub struct Metadata {
@@ -133,6 +141,9 @@ pub struct Metadata {
     pub workspace_root: PathBuf,
     /// Build directory
     pub target_directory: PathBuf,
+    /// The workspace-level metadata object. Null if non-existent.
+    #[serde(rename = "metadata", default, skip_serializing_if = "is_null")]
+    pub workspace_metadata: serde_json::Value,
     version: usize,
     #[doc(hidden)]
     #[serde(skip)]
@@ -305,7 +316,7 @@ pub struct Package {
     /// }
     ///
     /// ```
-    #[serde(default)]
+    #[serde(default, skip_serializing_if = "is_null")]
     pub metadata: serde_json::Value,
     /// The name of a native library the package is linking to.
     pub links: Option<String>,


Test patch:
diff --git a/tests/all/Cargo.toml b/tests/all/Cargo.toml
index e62b030..12832de 100644
--- a/tests/all/Cargo.toml
+++ b/tests/all/Cargo.toml
@@ -49,3 +49,9 @@ edition = '2015'
 [[bin]]
 name = "reqfeat"
 required-features = ["feat2"]
+
+[workspace]
+exclude = ["bdep", "benches", "devdep", "examples", "featdep", "namedep", "oldname", "path-dep", "windep"]
+
+[workspace.metadata.testobject]
+myvalue = "abc"
\ No newline at end of file
diff --git a/tests/test_samples.rs b/tests/test_samples.rs
index 2a8f74b..ab631d1 100644
--- a/tests/test_samples.rs
+++ b/tests/test_samples.rs
@@ -112,6 +112,7 @@ fn old_minimal() {
     );
     assert!(meta.resolve.is_none());
     assert_eq!(meta.workspace_root, PathBuf::from("/foo"));
+    assert_eq!(meta.workspace_metadata, serde_json::Value::Null);
     assert_eq!(meta.target_directory, PathBuf::from("/foo/target"));
 }
 
@@ -140,6 +141,16 @@ fn cargo_version() -> semver::Version {
     ver
 }
 
+#[derive(serde::Deserialize, PartialEq, Eq, Debug)]
+struct WorkspaceMetadata {
+    testobject: TestObject,
+}
+
+#[derive(serde::Deserialize, PartialEq, Eq, Debug)]
+struct TestObject {
+    myvalue: String,
+}
+
 #[test]
 fn all_the_fields() {
     // All the fields currently generated as of 1.47. This tries to exercise as
@@ -165,6 +176,14 @@ fn all_the_fields() {
         meta.workspace_root.file_name().unwrap(),
         PathBuf::from("all")
     );
+    assert_eq!(
+        serde_json::from_value::<WorkspaceMetadata>(meta.workspace_metadata).unwrap(),
+        WorkspaceMetadata {
+            testobject: TestObject {
+                myvalue: "abc".to_string()
+            }
+        }
+    );
     assert_eq!(meta.workspace_members.len(), 1);
     assert!(meta.workspace_members[0].to_string().starts_with("all"));