use super::*;
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename = "CiscoIPPhoneStatus", deny_unknown_fields)]
pub struct CiscoIpPhoneStatus {
#[serde(rename = "Text", default, skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[serde(rename = "Timer", default, skip_serializing_if = "Option::is_none")]
pub timer_seconds: Option<u16>,
#[serde(rename = "LocationX", default, skip_serializing_if = "Option::is_none")]
pub location_x: Option<i16>,
#[serde(rename = "LocationY", default, skip_serializing_if = "Option::is_none")]
pub location_y: Option<i16>,
#[serde(rename = "Width")]
pub width: u16,
#[serde(rename = "Height")]
pub height: u16,
#[serde(rename = "Depth")]
pub depth: u16,
#[serde(rename = "Data", default, skip_serializing_if = "Option::is_none")]
pub data: Option<PhoneBitmapData>,
}
impl CiscoIpPhoneStatus {
pub fn validate(&self) -> Result<(), PhoneXmlError> {
validate_optional_text("phone status text", self.text.as_deref(), 0, 32)?;
if self
.location_x
.is_some_and(|value| !(-1..=105).contains(&value))
{
return Err(PhoneXmlError::InvalidField {
field: "phone status horizontal location",
expected: "between -1 and 105",
});
}
if self
.location_y
.is_some_and(|value| !(-1..=20).contains(&value))
{
return Err(PhoneXmlError::InvalidField {
field: "phone status vertical location",
expected: "between -1 and 20",
});
}
if !(1..=106).contains(&self.width) {
return Err(PhoneXmlError::InvalidField {
field: "phone status width",
expected: "between 1 and 106",
});
}
if !(1..=21).contains(&self.height) {
return Err(PhoneXmlError::InvalidField {
field: "phone status height",
expected: "between 1 and 21",
});
}
if !(1..=2).contains(&self.depth) {
return Err(PhoneXmlError::InvalidField {
field: "phone status depth",
expected: "between 1 and 2",
});
}
if let Some(data) = &self.data {
validate_count(
"phone status bitmap bytes",
data.as_bytes().len(),
PHONE_STATUS_BITMAP_MAX_BYTES,
)?;
}
Ok(())
}
}
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename = "CiscoIPPhoneStatusFile", deny_unknown_fields)]
pub struct CiscoIpPhoneStatusFile {
#[serde(rename = "Text", default, skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[serde(rename = "Timer", default, skip_serializing_if = "Option::is_none")]
pub timer_seconds: Option<u16>,
#[serde(rename = "LocationX", default, skip_serializing_if = "Option::is_none")]
pub location_x: Option<i16>,
#[serde(rename = "LocationY", default, skip_serializing_if = "Option::is_none")]
pub location_y: Option<i16>,
#[serde(rename = "URL")]
pub url: PhoneImageUrl,
}
impl CiscoIpPhoneStatusFile {
pub fn validate(&self) -> Result<(), PhoneXmlError> {
validate_optional_text("phone status text", self.text.as_deref(), 0, 32)?;
if self
.location_x
.is_some_and(|value| !(-1..=261).contains(&value))
{
return Err(PhoneXmlError::InvalidField {
field: "phone status-file horizontal location",
expected: "between -1 and 261",
});
}
if self
.location_y
.is_some_and(|value| !(-1..=49).contains(&value))
{
return Err(PhoneXmlError::InvalidField {
field: "phone status-file vertical location",
expected: "between -1 and 49",
});
}
Ok(())
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum PhoneStatusDocument {
Bitmap(CiscoIpPhoneStatus),
File(CiscoIpPhoneStatusFile),
}
impl PhoneStatusDocument {
pub fn validate(&self) -> Result<(), PhoneXmlError> {
match self {
Self::Bitmap(document) => document.validate(),
Self::File(document) => document.validate(),
}
}
pub fn from_xml(document: &[u8]) -> Result<Self, PhoneXmlError> {
#[derive(serde::Deserialize)]
enum StatusDocumentEnvelope {
#[serde(rename = "CiscoIPPhoneStatus")]
Bitmap(CiscoIpPhoneStatus),
#[serde(rename = "CiscoIPPhoneStatusFile")]
File(CiscoIpPhoneStatusFile),
}
let document = match from_bytes(document, PHONE_STATUS_MAX_BYTES)? {
StatusDocumentEnvelope::Bitmap(document) => Self::Bitmap(document),
StatusDocumentEnvelope::File(document) => Self::File(document),
};
document.validate()?;
Ok(document)
}
pub fn to_xml(&self) -> Result<String, PhoneXmlError> {
self.to_xml_with_limit(PHONE_STATUS_MAX_BYTES)
}
pub fn to_xml_with_limit(&self, maximum_bytes: usize) -> Result<String, PhoneXmlError> {
self.validate()?;
match self {
Self::Bitmap(document) => to_string(document, maximum_bytes),
Self::File(document) => to_string(document, maximum_bytes),
}
}
}