use crate::error::Result;
use crate::protocol::header::Header;
use crate::protocol::message::IgtlMessage;
use crate::protocol::types::*;
#[derive(Debug)]
pub enum AnyMessage {
Transform(IgtlMessage<TransformMessage>),
Status(IgtlMessage<StatusMessage>),
Capability(IgtlMessage<CapabilityMessage>),
Image(IgtlMessage<ImageMessage>),
Position(IgtlMessage<PositionMessage>),
String(IgtlMessage<StringMessage>),
QtData(IgtlMessage<QtDataMessage>),
TData(IgtlMessage<TDataMessage>),
Sensor(IgtlMessage<SensorMessage>),
Point(IgtlMessage<PointMessage>),
Trajectory(IgtlMessage<TrajectoryMessage>),
NdArray(IgtlMessage<NdArrayMessage>),
Bind(IgtlMessage<BindMessage>),
ColorTable(IgtlMessage<ColorTableMessage>),
ImgMeta(IgtlMessage<ImgMetaMessage>),
LbMeta(IgtlMessage<LbMetaMessage>),
PolyData(IgtlMessage<PolyDataMessage>),
Video(IgtlMessage<VideoMessage>),
VideoMeta(IgtlMessage<VideoMetaMessage>),
Command(IgtlMessage<CommandMessage>),
GetTransform(IgtlMessage<GetTransformMessage>),
GetStatus(IgtlMessage<GetStatusMessage>),
GetCapability(IgtlMessage<GetCapabilityMessage>),
GetImage(IgtlMessage<GetImageMessage>),
GetImgMeta(IgtlMessage<GetImgMetaMessage>),
GetLbMeta(IgtlMessage<GetLbMetaMessage>),
GetPoint(IgtlMessage<GetPointMessage>),
GetTData(IgtlMessage<GetTDataMessage>),
RtsTransform(IgtlMessage<RtsTransformMessage>),
RtsStatus(IgtlMessage<RtsStatusMessage>),
RtsCapability(IgtlMessage<RtsCapabilityMessage>),
RtsImage(IgtlMessage<RtsImageMessage>),
RtsTData(IgtlMessage<RtsTDataMessage>),
StartTData(IgtlMessage<StartTDataMessage>),
StopTransform(IgtlMessage<StopTransformMessage>),
StopPosition(IgtlMessage<StopPositionMessage>),
StopQtData(IgtlMessage<StopQtDataMessage>),
StopTData(IgtlMessage<StopTDataMessage>),
StopImage(IgtlMessage<StopImageMessage>),
StopNdArray(IgtlMessage<StopNdArrayMessage>),
Unknown {
header: Header,
body: Vec<u8>,
},
}
impl AnyMessage {
pub fn message_type(&self) -> &str {
match self {
AnyMessage::Transform(_) => "TRANSFORM",
AnyMessage::Status(_) => "STATUS",
AnyMessage::Capability(_) => "CAPABILITY",
AnyMessage::Image(_) => "IMAGE",
AnyMessage::Position(_) => "POSITION",
AnyMessage::String(_) => "STRING",
AnyMessage::QtData(_) => "QTDATA",
AnyMessage::TData(_) => "TDATA",
AnyMessage::Sensor(_) => "SENSOR",
AnyMessage::Point(_) => "POINT",
AnyMessage::Trajectory(_) => "TRAJECTORY",
AnyMessage::NdArray(_) => "NDARRAY",
AnyMessage::Bind(_) => "BIND",
AnyMessage::ColorTable(_) => "COLORTABLE",
AnyMessage::ImgMeta(_) => "IMGMETA",
AnyMessage::LbMeta(_) => "LBMETA",
AnyMessage::PolyData(_) => "POLYDATA",
AnyMessage::Video(_) => "VIDEO",
AnyMessage::VideoMeta(_) => "VIDEOMETA",
AnyMessage::Command(_) => "COMMAND",
AnyMessage::GetTransform(_) => "GET_TRANSFORM",
AnyMessage::GetStatus(_) => "GET_STATUS",
AnyMessage::GetCapability(_) => "GET_CAPABILITY",
AnyMessage::GetImage(_) => "GET_IMAGE",
AnyMessage::GetImgMeta(_) => "GET_IMGMETA",
AnyMessage::GetLbMeta(_) => "GET_LBMETA",
AnyMessage::GetPoint(_) => "GET_POINT",
AnyMessage::GetTData(_) => "GET_TDATA",
AnyMessage::RtsTransform(_) => "RTS_TRANSFORM",
AnyMessage::RtsStatus(_) => "RTS_STATUS",
AnyMessage::RtsCapability(_) => "RTS_CAPABILITY",
AnyMessage::RtsImage(_) => "RTS_IMAGE",
AnyMessage::RtsTData(_) => "RTS_TDATA",
AnyMessage::StartTData(_) => "STT_TDATA",
AnyMessage::StopTransform(_) => "STP_TRANSFORM",
AnyMessage::StopPosition(_) => "STP_POSITION",
AnyMessage::StopQtData(_) => "STP_QTDATA",
AnyMessage::StopTData(_) => "STP_TDATA",
AnyMessage::StopImage(_) => "STP_IMAGE",
AnyMessage::StopNdArray(_) => "STP_NDARRAY",
AnyMessage::Unknown { header, .. } => header.type_name.as_str().unwrap_or("UNKNOWN"),
}
}
pub fn device_name(&self) -> Result<&str> {
let header = match self {
AnyMessage::Transform(msg) => &msg.header,
AnyMessage::Status(msg) => &msg.header,
AnyMessage::Capability(msg) => &msg.header,
AnyMessage::Image(msg) => &msg.header,
AnyMessage::Position(msg) => &msg.header,
AnyMessage::String(msg) => &msg.header,
AnyMessage::QtData(msg) => &msg.header,
AnyMessage::TData(msg) => &msg.header,
AnyMessage::Sensor(msg) => &msg.header,
AnyMessage::Point(msg) => &msg.header,
AnyMessage::Trajectory(msg) => &msg.header,
AnyMessage::NdArray(msg) => &msg.header,
AnyMessage::Bind(msg) => &msg.header,
AnyMessage::ColorTable(msg) => &msg.header,
AnyMessage::ImgMeta(msg) => &msg.header,
AnyMessage::LbMeta(msg) => &msg.header,
AnyMessage::PolyData(msg) => &msg.header,
AnyMessage::Video(msg) => &msg.header,
AnyMessage::VideoMeta(msg) => &msg.header,
AnyMessage::Command(msg) => &msg.header,
AnyMessage::GetTransform(msg) => &msg.header,
AnyMessage::GetStatus(msg) => &msg.header,
AnyMessage::GetCapability(msg) => &msg.header,
AnyMessage::GetImage(msg) => &msg.header,
AnyMessage::GetImgMeta(msg) => &msg.header,
AnyMessage::GetLbMeta(msg) => &msg.header,
AnyMessage::GetPoint(msg) => &msg.header,
AnyMessage::GetTData(msg) => &msg.header,
AnyMessage::RtsTransform(msg) => &msg.header,
AnyMessage::RtsStatus(msg) => &msg.header,
AnyMessage::RtsCapability(msg) => &msg.header,
AnyMessage::RtsImage(msg) => &msg.header,
AnyMessage::RtsTData(msg) => &msg.header,
AnyMessage::StartTData(msg) => &msg.header,
AnyMessage::StopTransform(msg) => &msg.header,
AnyMessage::StopPosition(msg) => &msg.header,
AnyMessage::StopQtData(msg) => &msg.header,
AnyMessage::StopTData(msg) => &msg.header,
AnyMessage::StopImage(msg) => &msg.header,
AnyMessage::StopNdArray(msg) => &msg.header,
AnyMessage::Unknown { header, .. } => header,
};
header.device_name.as_str()
}
pub fn header(&self) -> &Header {
match self {
AnyMessage::Transform(msg) => &msg.header,
AnyMessage::Status(msg) => &msg.header,
AnyMessage::Capability(msg) => &msg.header,
AnyMessage::Image(msg) => &msg.header,
AnyMessage::Position(msg) => &msg.header,
AnyMessage::String(msg) => &msg.header,
AnyMessage::QtData(msg) => &msg.header,
AnyMessage::TData(msg) => &msg.header,
AnyMessage::Sensor(msg) => &msg.header,
AnyMessage::Point(msg) => &msg.header,
AnyMessage::Trajectory(msg) => &msg.header,
AnyMessage::NdArray(msg) => &msg.header,
AnyMessage::Bind(msg) => &msg.header,
AnyMessage::ColorTable(msg) => &msg.header,
AnyMessage::ImgMeta(msg) => &msg.header,
AnyMessage::LbMeta(msg) => &msg.header,
AnyMessage::PolyData(msg) => &msg.header,
AnyMessage::Video(msg) => &msg.header,
AnyMessage::VideoMeta(msg) => &msg.header,
AnyMessage::Command(msg) => &msg.header,
AnyMessage::GetTransform(msg) => &msg.header,
AnyMessage::GetStatus(msg) => &msg.header,
AnyMessage::GetCapability(msg) => &msg.header,
AnyMessage::GetImage(msg) => &msg.header,
AnyMessage::GetImgMeta(msg) => &msg.header,
AnyMessage::GetLbMeta(msg) => &msg.header,
AnyMessage::GetPoint(msg) => &msg.header,
AnyMessage::GetTData(msg) => &msg.header,
AnyMessage::RtsTransform(msg) => &msg.header,
AnyMessage::RtsStatus(msg) => &msg.header,
AnyMessage::RtsCapability(msg) => &msg.header,
AnyMessage::RtsImage(msg) => &msg.header,
AnyMessage::RtsTData(msg) => &msg.header,
AnyMessage::StartTData(msg) => &msg.header,
AnyMessage::StopTransform(msg) => &msg.header,
AnyMessage::StopPosition(msg) => &msg.header,
AnyMessage::StopQtData(msg) => &msg.header,
AnyMessage::StopTData(msg) => &msg.header,
AnyMessage::StopImage(msg) => &msg.header,
AnyMessage::StopNdArray(msg) => &msg.header,
AnyMessage::Unknown { header, .. } => header,
}
}
pub fn as_transform(&self) -> Option<&IgtlMessage<TransformMessage>> {
match self {
AnyMessage::Transform(msg) => Some(msg),
_ => None,
}
}
pub fn as_status(&self) -> Option<&IgtlMessage<StatusMessage>> {
match self {
AnyMessage::Status(msg) => Some(msg),
_ => None,
}
}
pub fn as_image(&self) -> Option<&IgtlMessage<ImageMessage>> {
match self {
AnyMessage::Image(msg) => Some(msg),
_ => None,
}
}
pub fn as_position(&self) -> Option<&IgtlMessage<PositionMessage>> {
match self {
AnyMessage::Position(msg) => Some(msg),
_ => None,
}
}
pub fn as_string(&self) -> Option<&IgtlMessage<StringMessage>> {
match self {
AnyMessage::String(msg) => Some(msg),
_ => None,
}
}
pub fn as_capability(&self) -> Option<&IgtlMessage<CapabilityMessage>> {
match self {
AnyMessage::Capability(msg) => Some(msg),
_ => None,
}
}
pub fn is_unknown(&self) -> bool {
matches!(self, AnyMessage::Unknown { .. })
}
pub fn decode_with_options(data: &[u8], verify_crc: bool) -> Result<Self> {
use crate::error::IgtlError;
let header = Header::decode(&data[..Header::SIZE])?;
let type_name = header.type_name.as_str()?;
match type_name {
"TRANSFORM" => {
if let Ok(msg) =
IgtlMessage::<TransformMessage>::decode_with_options(data, verify_crc)
{
return Ok(AnyMessage::Transform(msg));
}
}
"STATUS" => {
if let Ok(msg) = IgtlMessage::<StatusMessage>::decode_with_options(data, verify_crc)
{
return Ok(AnyMessage::Status(msg));
}
}
"CAPABILITY" => {
if let Ok(msg) =
IgtlMessage::<CapabilityMessage>::decode_with_options(data, verify_crc)
{
return Ok(AnyMessage::Capability(msg));
}
}
"IMAGE" => {
if let Ok(msg) = IgtlMessage::<ImageMessage>::decode_with_options(data, verify_crc)
{
return Ok(AnyMessage::Image(msg));
}
}
"POSITION" => {
if let Ok(msg) =
IgtlMessage::<PositionMessage>::decode_with_options(data, verify_crc)
{
return Ok(AnyMessage::Position(msg));
}
}
"STRING" => {
if let Ok(msg) = IgtlMessage::<StringMessage>::decode_with_options(data, verify_crc)
{
return Ok(AnyMessage::String(msg));
}
}
"QTDATA" => {
if let Ok(msg) = IgtlMessage::<QtDataMessage>::decode_with_options(data, verify_crc)
{
return Ok(AnyMessage::QtData(msg));
}
}
"TDATA" => {
if let Ok(msg) = IgtlMessage::<TDataMessage>::decode_with_options(data, verify_crc)
{
return Ok(AnyMessage::TData(msg));
}
}
"SENSOR" => {
if let Ok(msg) = IgtlMessage::<SensorMessage>::decode_with_options(data, verify_crc)
{
return Ok(AnyMessage::Sensor(msg));
}
}
"POINT" => {
if let Ok(msg) = IgtlMessage::<PointMessage>::decode_with_options(data, verify_crc)
{
return Ok(AnyMessage::Point(msg));
}
}
_ => {
let body = data[Header::SIZE..].to_vec();
return Ok(AnyMessage::Unknown { header, body });
}
}
Err(IgtlError::UnknownMessageType(type_name.to_string()))
}
}