use crate::enum_map;
use anyhow::bail;
use serde::Serialize;
use std::convert::{TryFrom, TryInto};
use strum_macros::{Display, EnumIter};
#[derive(Debug, Clone, Copy, Eq, PartialEq, EnumIter, Display, Serialize, Hash)]
pub enum Target {
Io,
Web,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, EnumIter, Display, Serialize, Hash)]
pub enum TargetOrCommon {
Common,
Io,
Web,
}
enum_map!(
TargetOrCommonMap, TargetOrCommon;
Common, Io, Web;
common, io, web;
);
impl TryFrom<TargetOrCommon> for Target {
type Error = anyhow::Error;
fn try_from(src: TargetOrCommon) -> Result<Self, Self::Error> {
Ok(match src {
TargetOrCommon::Common => bail!("Cannot convert TargetOrCommon::Common to Target"),
TargetOrCommon::Io => Target::Io,
TargetOrCommon::Web => Target::Web,
})
}
}
impl From<Target> for TargetOrCommon {
fn from(value: Target) -> Self {
match value {
Target::Io => TargetOrCommon::Io,
Target::Web => TargetOrCommon::Web,
}
}
}
impl TargetOrCommon {
pub(crate) fn as_target_or(&self, when_common: Target) -> Target {
match self {
TargetOrCommon::Common => when_common,
TargetOrCommon::Io | TargetOrCommon::Web => (*self).try_into().unwrap(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn converts_platform_targets_bidirectionally() {
assert_eq!(Target::try_from(TargetOrCommon::Io).unwrap(), Target::Io);
assert_eq!(Target::try_from(TargetOrCommon::Web).unwrap(), Target::Web);
assert_eq!(TargetOrCommon::from(Target::Io), TargetOrCommon::Io);
assert_eq!(TargetOrCommon::from(Target::Web), TargetOrCommon::Web);
}
#[test]
fn resolves_common_and_platform_targets() {
assert_eq!(TargetOrCommon::Common.as_target_or(Target::Io), Target::Io);
assert_eq!(TargetOrCommon::Io.as_target_or(Target::Web), Target::Io);
assert_eq!(TargetOrCommon::Web.as_target_or(Target::Io), Target::Web);
}
}