use crate::core::{InternedString, Target};
use crate::util::errors::{CargoResult, CargoResultExt};
use serde::Serialize;
use std::path::Path;
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy, PartialOrd, Ord)]
pub enum CompileKind {
Host,
Target(CompileTarget),
}
impl CompileKind {
pub fn is_host(&self) -> bool {
match self {
CompileKind::Host => true,
_ => false,
}
}
pub fn for_target(self, target: &Target) -> CompileKind {
match self {
CompileKind::Host => CompileKind::Host,
CompileKind::Target(_) if target.for_host() => CompileKind::Host,
CompileKind::Target(n) => CompileKind::Target(n),
}
}
}
impl serde::ser::Serialize for CompileKind {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
match self {
CompileKind::Host => None::<&str>.serialize(s),
CompileKind::Target(t) => Some(t.name).serialize(s),
}
}
}
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy, PartialOrd, Ord, Serialize)]
pub struct CompileTarget {
name: InternedString,
}
impl CompileTarget {
pub fn new(name: &str) -> CargoResult<CompileTarget> {
let name = name.trim();
if name.is_empty() {
anyhow::bail!("target was empty");
}
if !name.ends_with(".json") {
return Ok(CompileTarget { name: name.into() });
}
let path = Path::new(name)
.canonicalize()
.chain_err(|| anyhow::format_err!("target path {:?} is not a valid file", name))?;
let name = path
.into_os_string()
.into_string()
.map_err(|_| anyhow::format_err!("target path is not valid unicode"))?;
Ok(CompileTarget { name: name.into() })
}
pub fn rustc_target(&self) -> &str {
&self.name
}
pub fn short_name(&self) -> &str {
if self.name.ends_with(".json") {
Path::new(&self.name).file_stem().unwrap().to_str().unwrap()
} else {
&self.name
}
}
}