use anyhow::Context;
use std::str::FromStr;
use strum_macros::{AsRefStr, EnumString, FromRepr};
pub type InputSourceRaw = u8;
#[derive(Copy, Clone, Debug, PartialEq, AsRefStr, EnumString, FromRepr)]
#[repr(u8)]
#[strum(ascii_case_insensitive)]
pub enum InputSource {
#[strum(serialize = "DP1")]
DisplayPort1 = 0x0F,
#[strum(serialize = "DP2")]
DisplayPort2 = 0x10,
Hdmi1 = 0x11,
Hdmi2 = 0x12,
UsbC1 = 0x19,
UsbC2 = 0x1B,
}
impl InputSource {
pub fn as_raw(self) -> InputSourceRaw {
self as InputSourceRaw
}
pub fn raw_from_str(input: &str) -> anyhow::Result<InputSourceRaw> {
if let Ok(value) = input.parse::<InputSourceRaw>() {
return Ok(value);
}
InputSource::from_str(input)
.map(|value| value.as_raw())
.with_context(|| format!("\"{input}\" is not a valid input source"))
}
pub fn str_from_raw(value: InputSourceRaw) -> String {
match InputSource::from_repr(value) {
Some(input_source) => input_source.as_ref().to_string(),
None => value.to_string(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn input_source_from_str() {
assert_eq!(InputSource::from_str("Hdmi1"), Ok(InputSource::Hdmi1));
assert_eq!(InputSource::from_str("hdmi1"), Ok(InputSource::Hdmi1));
assert_eq!(InputSource::from_str("HDMI1"), Ok(InputSource::Hdmi1));
assert_eq!(InputSource::from_str("DP1"), Ok(InputSource::DisplayPort1));
assert_eq!(InputSource::from_str("dp2"), Ok(InputSource::DisplayPort2));
assert!(InputSource::from_str("xyz").is_err());
}
}