1use std::path::PathBuf;
2
3use anyhow::{anyhow, Result};
4use serde::Deserialize;
5
6#[derive(Debug, Hash)]
7pub struct Config {
8 pub memcpy: bool,
9 pub sysroot_path: PathBuf,
10 pub panic_immediate_abort: bool,
11}
12
13#[derive(Debug, Deserialize, Default)]
14struct ParseConfig {
15 pub memcpy: Option<bool>,
16 pub sysroot_path: Option<String>,
17 pub panic_immediate_abort: Option<bool>,
18}
19
20impl Config {
21 pub fn from_metadata(metadata: &cargo_metadata::Metadata, quiet: bool) -> Result<Config> {
22 let root_manifest = metadata.workspace_root.join("Cargo.toml");
23 let root_package = metadata
24 .packages
25 .iter()
26 .find(|package| package.manifest_path == root_manifest);
27
28 let config = match root_package {
29 Some(root_package) => {
30 let crate_metadata = root_package.metadata.get("cargo-xbuild");
31 match crate_metadata {
32 Some(json) => serde_json::from_value(json.clone()).map_err(|e| {
33 anyhow!(
34 "parsing package.metadata.cargo-xbuild section failed: {}",
35 e
36 )
37 })?,
38 None => ParseConfig::default(),
39 }
40 }
41 None => {
42 if !quiet {
52 eprintln!(
53 "WARNING: There is no root package to read the cargo-xbuild config from."
54 );
55 }
56 ParseConfig::default()
58 }
59 };
60
61 Ok(Config {
62 memcpy: config.memcpy.unwrap_or(true),
63 sysroot_path: PathBuf::from(config.sysroot_path.unwrap_or("target/sysroot".into())),
64 panic_immediate_abort: config.panic_immediate_abort.unwrap_or(false),
65 })
66 }
67}