use std::str::FromStr;
#[non_exhaustive]
#[derive(Clone, Debug, PartialEq)]
pub enum BuildProfile {
Cross,
Pkg(String, String),
Stage1,
Stage2,
NoBiarch,
NoCheck,
NoCil,
NoDoc,
NoGir,
NoGolang,
NoInsttest,
NoJava,
NoPerl,
NoPython,
NoRuby,
NoLua,
NoGuile,
NoOcaml,
NoWasm,
NoWindows,
NoUdeb,
UpstreamCargo,
Unknown(String),
}
#[allow(unused_macros)]
macro_rules! build_profile_table_tests {
( $( ( $id:ident, $name:expr, $bp:path ) ),* ) => {
$(
#[test]
fn $id() {
let bp: BuildProfile = $name.parse().unwrap();
assert_eq!(&bp.to_string(), $name);
}
)*
};
}
macro_rules! build_profile_table_as_str {
( $( ( $id:ident, $name:expr, $bp:path ) ),* ) => {
impl std::fmt::Display for BuildProfile {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", match self {
$( $bp => $name.to_owned(), )*
Self::Unknown(v) => v.to_owned(),
Self::Pkg(source, anything) => format!("pkg.{}.{}", source, anything),
})
}
}
}
}
macro_rules! build_profile_table_from_str {
( $( ( $id:ident, $name:expr, $bp:path ) ),* ) => {
impl FromStr for BuildProfile {
type Err = Error;
fn from_str(bp: &str) -> Result<Self, Error> {
if bp.starts_with("pkg.") {
match bp.splitn(3, '.').collect::<Vec<_>>()[..] {
[_, package, anything] => {
return Ok(Self::Pkg(package.to_owned(), anything.to_owned()))
}
_ => {
return Err(Error::InvalidPkgFormat)
}
}
}
Ok(match bp {
$( $name => $bp, )*
_ => BuildProfile::Unknown(bp.to_owned()),
})
}
}
}
}
macro_rules! build_profile_table {
( $( ( $id:ident, $name:expr, $bp:path ) ),* ) => {
build_profile_table_from_str!($( ($id, $name, $bp) ),*);
build_profile_table_as_str!($( ($id, $name, $bp) ),*);
#[cfg(test)]
mod arch_tests {
use super::*;
build_profile_table_tests!($( ($id, $name, $bp) ),*);
}
};
}
build_profile_table!(
(cross, "cross", BuildProfile::Cross),
(stage1, "stage1", BuildProfile::Stage1),
(stage2, "stage2", BuildProfile::Stage2),
(nobiarch, "nobiarch", BuildProfile::NoBiarch),
(nocheck, "nocheck", BuildProfile::NoCheck),
(nocil, "nocil", BuildProfile::NoCil),
(nodoc, "nodoc", BuildProfile::NoDoc),
(nogir, "nogir", BuildProfile::NoGir),
(nogolang, "nogolang", BuildProfile::NoGolang),
(noinsttest, "noinsttest", BuildProfile::NoInsttest),
(nojava, "nojava", BuildProfile::NoJava),
(noperl, "noperl", BuildProfile::NoPerl),
(nopython, "nopython", BuildProfile::NoPython),
(noruby, "noruby", BuildProfile::NoRuby),
(nolua, "nolua", BuildProfile::NoLua),
(noguile, "noguile", BuildProfile::NoGuile),
(noocaml, "noocaml", BuildProfile::NoOcaml),
(nowasm, "nowasm", BuildProfile::NoWasm),
(nowindows, "nowindows", BuildProfile::NoWindows),
(noudeb, "noudeb", BuildProfile::NoUdeb),
(
upstream_cargo,
"upstream-cargo",
BuildProfile::UpstreamCargo
)
);
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Error {
InvalidPkgFormat,
}
crate::errors::error_enum!(Error);
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_pkg() {
let bp: BuildProfile = "pkg.foo.bar".parse().unwrap();
assert_eq!(BuildProfile::Pkg("foo".to_owned(), "bar".to_owned()), bp);
}
#[test]
fn test_unknown() {
let bp: BuildProfile = "hello".parse().unwrap();
assert_eq!(BuildProfile::Unknown("hello".to_owned()), bp);
}
}
#[cfg(feature = "serde")]
mod serde {
use super::BuildProfile;
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as DeError};
impl Serialize for BuildProfile {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
String::serialize(&self.to_string(), serializer)
}
}
impl<'de> Deserialize<'de> for BuildProfile {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let s = String::deserialize(d)?;
s.parse().map_err(|e| D::Error::custom(format!("{e:?}")))
}
}
}