use crate::types::DxValue;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DxFormat {
Zero,
Text,
Unknown,
}
#[inline]
pub fn detect_format(bytes: &[u8]) -> DxFormat {
if bytes.len() < 2 {
return DxFormat::Unknown;
}
match &bytes[0..2] {
[0x5A, 0x44] => DxFormat::Zero, [0x44, 0x58] => DxFormat::Text, _ => DxFormat::Unknown,
}
}
pub fn parse_auto(bytes: &[u8]) -> Result<DxValue, String> {
match detect_format(bytes) {
DxFormat::Zero => {
Err(
"DX-Machine to DxValue conversion not yet implemented (use direct struct access)"
.to_string(),
)
}
DxFormat::Text | DxFormat::Unknown => {
crate::parse(bytes).map_err(|e| format!("Parse error: {:?}", e))
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum FormatMode {
Zero,
Text,
#[default]
Auto,
}
impl FormatMode {
pub fn from_str(s: &str) -> Option<Self> {
match s.to_lowercase().as_str() {
"zero" | "binary" => Some(Self::Zero),
"text" | "dsr" => Some(Self::Text),
"auto" => Some(Self::Auto),
_ => None,
}
}
pub fn name(&self) -> &'static str {
match self {
Self::Zero => "zero",
Self::Text => "text",
Self::Auto => "auto",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_detect_zero_format() {
let bytes = [0x5A, 0x44, 0x01, 0x04]; assert_eq!(detect_format(&bytes), DxFormat::Zero);
}
#[test]
fn test_detect_text_format() {
let bytes = [0x44, 0x58, b'_', b'I']; assert_eq!(detect_format(&bytes), DxFormat::Text);
}
#[test]
fn test_detect_unknown() {
let bytes = [0x00, 0x00, 0x00, 0x00];
assert_eq!(detect_format(&bytes), DxFormat::Unknown);
}
#[test]
fn test_detect_too_small() {
let bytes = [0x5A];
assert_eq!(detect_format(&bytes), DxFormat::Unknown);
}
#[test]
fn test_format_mode_from_str() {
assert_eq!(FormatMode::from_str("zero"), Some(FormatMode::Zero));
assert_eq!(FormatMode::from_str("text"), Some(FormatMode::Text));
assert_eq!(FormatMode::from_str("dsr"), Some(FormatMode::Text));
assert_eq!(FormatMode::from_str("auto"), Some(FormatMode::Auto));
assert_eq!(FormatMode::from_str("binary"), Some(FormatMode::Zero));
assert_eq!(FormatMode::from_str("invalid"), None);
}
#[test]
fn test_format_mode_name() {
assert_eq!(FormatMode::Zero.name(), "zero");
assert_eq!(FormatMode::Text.name(), "text");
assert_eq!(FormatMode::Auto.name(), "auto");
}
}