Skip to content

Commit

Permalink
Merge pull request #7 from dtolnay/defer
Browse files Browse the repository at this point in the history
Report parse error on package.metadata.docs.rs only for workspace members
  • Loading branch information
dtolnay authored Jan 13, 2024
2 parents 7707ba5 + 146be0d commit 3b7cd04
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
19 changes: 16 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use clap::{CommandFactory as _, Parser as _};
use std::collections::BTreeMap as Map;
use std::env;
use std::io::{self, Write as _};
use std::mem;
use std::process::{self, Command, Stdio};

cargo_subcommand_metadata::description!("Imitate the documentation build that docs.rs would do");
Expand Down Expand Up @@ -47,14 +48,26 @@ fn do_main() -> Result<()> {
}

let mut json = serde_json::Deserializer::from_slice(&output.stdout);
let metadata: Metadata = serde_path_to_error::deserialize(&mut json)
let mut metadata: Metadata = serde_path_to_error::deserialize(&mut json)
.context("Failed to parse output of `cargo metadata`")?;

let mut packages = Map::new();
for pkg in metadata.packages {
packages.insert(pkg.id.clone(), pkg);
}

for workspace_member in &mut metadata.workspace_members {
let package = packages.get_mut(workspace_member).unwrap();
if package.metadata.is_err() {
let metadata_error =
mem::replace(&mut package.metadata, Ok(DocumentationOptions::default()))
.unwrap_err();
let name = &package.name;
let context = format!("failed to parse `package.metadata.docs.rs` for {name}");
return Err(anyhow::Error::new(metadata_error).context(context));
}
}

let default_documentation_options = DocumentationOptions::default();
let mut proc_macro = false;
let metadata = if let Some(package) = &args.package {
Expand All @@ -63,15 +76,15 @@ fn do_main() -> Result<()> {
if packages[workspace_member].name == *package {
let package = &packages[workspace_member];
proc_macro = package.is_proc_macro();
package_metadata = &package.metadata;
package_metadata = package.metadata.as_ref().unwrap();
break;
}
}
package_metadata
} else if let Some(root) = metadata.resolve.root {
let package = &packages[&root];
proc_macro = package.is_proc_macro();
&package.metadata
package.metadata.as_ref().unwrap()
} else {
let mut options = String::new();
for (i, member) in metadata.workspace_members.iter().enumerate() {
Expand Down
16 changes: 12 additions & 4 deletions src/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use serde::de::{Deserialize, Deserializer};
use serde_derive::Deserialize;
use serde_json::Value;

#[derive(Deserialize, Debug)]
pub struct Metadata {
Expand All @@ -14,7 +15,7 @@ pub struct Package {
pub id: PackageId,
pub targets: Vec<Target>,
#[serde(deserialize_with = "deserialize_docs_rs")]
pub metadata: DocumentationOptions,
pub metadata: Result<DocumentationOptions, serde_path_to_error::Error<serde_json::Error>>,
}

#[derive(Deserialize, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
Expand Down Expand Up @@ -58,7 +59,9 @@ pub struct DocumentationOptions {
pub cargo_args: Vec<String>,
}

fn deserialize_docs_rs<'de, D>(deserializer: D) -> Result<DocumentationOptions, D::Error>
fn deserialize_docs_rs<'de, D>(
deserializer: D,
) -> Result<Result<DocumentationOptions, serde_path_to_error::Error<serde_json::Error>>, D::Error>
where
D: Deserializer<'de>,
{
Expand All @@ -69,11 +72,16 @@ where

#[derive(Deserialize)]
struct Inner {
pub rs: Option<DocumentationOptions>,
pub rs: Option<Value>,
}

let outer: Option<Outer> = Deserialize::deserialize(deserializer)?;
Ok((|| outer?.docs?.rs)().unwrap_or_default())
let Some(value) = (|| outer?.docs?.rs)() else {
let default = Ok(DocumentationOptions::default());
return Ok(default);
};

Ok(serde_path_to_error::deserialize(value))
}

impl Package {
Expand Down

0 comments on commit 3b7cd04

Please sign in to comment.