use serde::{Deserialize, Serialize};
use super::characteristic::Characteristic;
use super::MOD_PATH;
use crate::common::attachment::AttachmentRefOrValue;
use crate::common::related_party::RelatedParty;
use crate::common::tmf_error::TMFError;
use crate::{HasAttachment, HasId, HasName, HasRelatedParty};
use tmflib_derive::{HasAttachment, HasId, HasName, HasRelatedParty};
const CLASS_PATH: &str = "resource";
const RESOURCE_VERS: &str = "1.0";
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
pub enum ResourceUsageStateType {
#[default]
Idle,
Active,
Busy,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
pub enum ResourceAdministrativeStateType {
Locked,
#[default]
Unlocked,
Shutdown,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
pub enum ResourceOperationalStateType {
#[default]
Enable,
Disable,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
pub enum ResourceStatusType {
Standby,
Alarm,
#[default]
Available,
Reserved,
Unknown,
Suspended,
}
#[derive(
Clone, Debug, Default, Deserialize, HasId, HasName, HasAttachment, HasRelatedParty, Serialize,
)]
#[serde(rename_all = "camelCase")]
pub struct Resource {
pub administrative_state: ResourceAdministrativeStateType,
#[serde(skip_serializing_if = "Option::is_none")]
pub attachment: Option<Vec<AttachmentRefOrValue>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub href: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub operational_state: ResourceOperationalStateType,
#[serde(skip_serializing_if = "Option::is_none")]
pub resource_characteristic: Option<Vec<Characteristic>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub resource_status: Option<ResourceStatusType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub resource_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub related_party: Option<Vec<RelatedParty>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub usage_state: Option<ResourceUsageStateType>,
}
impl Resource {
pub fn new(name: impl Into<String>) -> Resource {
let mut resource = Resource::create();
resource.name = Some(name.into());
resource.resource_version = Some(RESOURCE_VERS.to_owned());
resource
}
}
#[cfg(test)]
mod test {
use crate::common::related_party::RelatedParty;
#[cfg(feature = "build-V4")]
use crate::tmf632::individual_v4::Individual;
#[cfg(feature = "build-V5")]
use crate::tmf632::individual_v5::Individual;
use super::*;
const RESOURCE_NAME: &str = "ResourceName";
const RESOUCEUSAGESTATE_JSON: &str = "\"Idle\"";
const RESOUCEADMINADMINSTATE_JSON: &str = "\"Unlocked\"";
const RESOUCEOPSSTATE_JSON: &str = "\"Enable\"";
const RESOUCESTATE_JSON: &str = "\"Available\"";
const RESOURCE_JSON: &str = "{
\"administrativeState\" : \"Unlocked\",
\"name\" : \"ResourceName\",
\"operationalState\" : \"Enable\",
\"resourceCharacteristic\" : [],
\"resourceStatus\" : \"Available\",
\"resourceVersion\" : \"1.0\",
\"usageState\" : \"Idle\"
}";
const INDIVIDUAL_NAME: &str = "An Individual";
#[test]
fn test_resource_new() {
let resource = Resource::new(RESOURCE_NAME);
assert_eq!(resource.get_name().as_str(), RESOURCE_NAME);
assert_eq!(resource.resource_version.is_some(), true);
assert_eq!(resource.resource_version.unwrap(), RESOURCE_VERS);
}
#[test]
fn test_resourceusagestate_deserialize() {
let resourceusagestate: ResourceUsageStateType =
serde_json::from_str(RESOUCEUSAGESTATE_JSON).unwrap();
assert_eq!(resourceusagestate, ResourceUsageStateType::Idle);
}
#[test]
fn test_resourceadminstate_deserialize() {
let resourceadminstate: ResourceAdministrativeStateType =
serde_json::from_str(RESOUCEADMINADMINSTATE_JSON).unwrap();
assert_eq!(
resourceadminstate,
ResourceAdministrativeStateType::Unlocked
);
}
#[test]
fn test_resourceopsstate_deserialize() {
let resourceopsstate: ResourceOperationalStateType =
serde_json::from_str(RESOUCEOPSSTATE_JSON).unwrap();
assert_eq!(resourceopsstate, ResourceOperationalStateType::Enable);
}
#[test]
fn test_resourcestate_deseralize() {
let resourcestate: ResourceStatusType = serde_json::from_str(RESOUCESTATE_JSON).unwrap();
assert_eq!(resourcestate, ResourceStatusType::Available);
}
#[test]
fn test_resource_deserialize() {
let resource: Resource = serde_json::from_str(RESOURCE_JSON).unwrap();
assert_eq!(resource.get_name().as_str(), "ResourceName");
assert_eq!(resource.resource_version.is_some(), true);
assert_eq!(resource.resource_version.unwrap().as_str(), "1.0");
assert_eq!(
resource.administrative_state,
ResourceAdministrativeStateType::Unlocked
);
assert_eq!(
resource.operational_state,
ResourceOperationalStateType::Enable
);
assert_eq!(resource.usage_state, Some(ResourceUsageStateType::Idle));
}
#[test]
fn test_resource_hasattachment() {
let mut resource = Resource::new(RESOURCE_NAME);
let attach = AttachmentRefOrValue::new();
resource.add(&attach);
assert_eq!(resource.attachment.is_some(), true);
assert_eq!(resource.attachment.unwrap().len(), 1);
}
#[test]
fn test_resource_hasrelatedparty() {
let party = Individual::new(INDIVIDUAL_NAME);
let mut resource = Resource::new(RESOURCE_NAME);
resource.add_party(RelatedParty::from(&party));
assert_eq!(resource.related_party.is_some(), true);
assert_eq!(resource.related_party.unwrap().len(), 1);
}
}