use crate::{graph::PackageGraph, Error};
use cargo_metadata::CargoOpt;
use serde::{Deserialize, Serialize};
use std::{convert::TryFrom, io, path::PathBuf, process::Command};
#[derive(Clone, Debug, Default)]
pub struct MetadataCommand {
inner: cargo_metadata::MetadataCommand,
}
impl MetadataCommand {
pub fn new() -> Self {
let mut inner = cargo_metadata::MetadataCommand::new();
inner.features(CargoOpt::AllFeatures);
Self { inner }
}
pub fn cargo_path(&mut self, path: impl Into<PathBuf>) -> &mut Self {
self.inner.cargo_path(path);
self
}
pub fn manifest_path(&mut self, path: impl Into<PathBuf>) -> &mut Self {
self.inner.manifest_path(path);
self
}
pub fn current_dir(&mut self, path: impl Into<PathBuf>) -> &mut Self {
self.inner.current_dir(path);
self
}
pub fn no_deps(&mut self) -> &mut Self {
self.inner.no_deps();
self
}
pub fn other_options(
&mut self,
options: impl IntoIterator<Item = impl Into<String>>,
) -> &mut Self {
self.inner
.other_options(options.into_iter().map(|s| s.into()).collect::<Vec<_>>());
self
}
pub fn cargo_command(&self) -> Command {
self.inner.cargo_command()
}
pub fn exec(&self) -> Result<CargoMetadata, Error> {
let inner = self.inner.exec().map_err(Error::command_error)?;
Ok(CargoMetadata(inner))
}
pub fn build_graph(&self) -> Result<PackageGraph, Error> {
let metadata = self.exec()?;
metadata.build_graph()
}
}
impl TryFrom<MetadataCommand> for PackageGraph {
type Error = Error;
fn try_from(command: MetadataCommand) -> Result<Self, Self::Error> {
command.build_graph()
}
}
impl<'a> TryFrom<&'a MetadataCommand> for PackageGraph {
type Error = Error;
fn try_from(command: &'a MetadataCommand) -> Result<Self, Self::Error> {
command.build_graph()
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
pub struct CargoMetadata(pub(crate) cargo_metadata::Metadata);
impl CargoMetadata {
pub fn parse_json(json: impl AsRef<str>) -> Result<Self, Error> {
let inner = serde_json::from_str(json.as_ref()).map_err(Error::MetadataParseError)?;
Ok(Self(inner))
}
pub fn serialize(&self, writer: &mut impl io::Write) -> Result<(), Error> {
serde_json::to_writer(writer, &self.0).map_err(Error::MetadataSerializeError)
}
pub fn build_graph(self) -> Result<PackageGraph, Error> {
PackageGraph::from_metadata(self)
}
}
impl TryFrom<CargoMetadata> for PackageGraph {
type Error = Error;
fn try_from(metadata: CargoMetadata) -> Result<Self, Self::Error> {
metadata.build_graph()
}
}