fluvio_index/target.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
use std::fmt;
use serde::{Serialize, Deserialize};
use crate::Error;
use std::borrow::Cow;
const PACKAGE_TARGET: &str = env!("PACKAGE_TARGET");
/// Detects the target triple of the current build and returns
/// the name of a compatible build target on packages.fluvio.io.
///
/// Returns `Some(Target)` if there is a compatible target, or
/// `None` if this target is unsupported or has no compatible target.
pub fn package_target() -> Result<Target, Error> {
let target = PACKAGE_TARGET.parse()?;
Ok(target)
}
/// An object representing a specific build target for an artifact
/// being managed by fluvio-index.
///
/// This type is generally constructed using `FromStr` via the
/// `parse` method.
///
/// # Example
///
/// ```
/// # use fluvio_index::Target;
/// let target: Target = "x86_64-unknown-linux-musl".parse().unwrap();
/// ```
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize)]
#[serde(transparent)]
pub struct Target(Cow<'static, str>);
#[allow(non_upper_case_globals)]
impl Target {
// These constants are from back when `Target` was an enum.
// Their variants are now constants, so constructors should not have broken
pub const X86_64AppleDarwin: Target = Target(Cow::Borrowed("x86_64-apple-darwin"));
pub const X86_64UnknownLinuxMusl: Target = Target(Cow::Borrowed("x86_64-unknown-linux-musl"));
pub const ALL_TARGETS: &'static [Target] =
&[Target::X86_64AppleDarwin, Target::X86_64UnknownLinuxMusl];
pub fn as_str(&self) -> &str {
self.0.as_ref()
}
}
impl std::str::FromStr for Target {
type Err = Error;
/// When parsing from a string, here is the chance to make any
/// edits or to collapse multiple target names into one. An
/// example of this is how we transform the target name
/// `x86_64-unknown-linux-gnu` into `x86_64-unknown-linux-musl`.
///
/// Additionally, if there are any "target strings" that we
/// know for a fact that we cannot support, we can identify
/// those strings here and manually reject them in order to
/// prevent downstream tooling from incorrectly allowing those
/// targets.
///
/// All other target names should pass through unchanged.
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let platform = match s {
"x86_64-apple-darwin" => Self::X86_64AppleDarwin,
"x86_64-unknown-linux-musl" => Self::X86_64UnknownLinuxMusl,
"x86_64-unknown-linux-gnu" => Self::X86_64UnknownLinuxMusl,
other => Self(Cow::Owned(other.to_owned())),
};
Ok(platform)
}
}
impl fmt::Display for Target {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl<'de> Deserialize<'de> for Target {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let string = String::deserialize(deserializer)?;
let me: Self = std::str::FromStr::from_str(&string).map_err(|e: Error| {
serde::de::Error::invalid_value(
serde::de::Unexpected::Other(&e.to_string()),
&"valid Target",
)
})?;
Ok(me)
}
}