tss_esapi/structures/lists/
command_code_attributes.rs1use crate::{
4 attributes::CommandCodeAttributes,
5 tss2_esys::{TPMA_CC, TPML_CCA},
6 Error, Result, WrapperErrorKind,
7};
8use log::error;
9use std::{convert::TryFrom, iter::IntoIterator, ops::Deref};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct CommandCodeAttributesList {
17 command_code_attributes: Vec<CommandCodeAttributes>,
18}
19
20impl CommandCodeAttributesList {
21 pub const MAX_SIZE: usize = Self::calculate_max_size();
22
23 pub fn find(&self, command_index: u16) -> Option<&CommandCodeAttributes> {
26 self.command_code_attributes
27 .iter()
28 .find(|cca| cca.command_index() == command_index)
29 }
30
31 const fn calculate_max_size() -> usize {
34 crate::structures::capability_data::max_cap_size::<TPMA_CC>()
35 }
36}
37
38impl Deref for CommandCodeAttributesList {
39 type Target = Vec<CommandCodeAttributes>;
40
41 fn deref(&self) -> &Self::Target {
42 &self.command_code_attributes
43 }
44}
45
46impl AsRef<[CommandCodeAttributes]> for CommandCodeAttributesList {
47 fn as_ref(&self) -> &[CommandCodeAttributes] {
48 self.command_code_attributes.as_slice()
49 }
50}
51
52impl TryFrom<Vec<CommandCodeAttributes>> for CommandCodeAttributesList {
53 type Error = Error;
54
55 fn try_from(command_code_attributes: Vec<CommandCodeAttributes>) -> Result<Self> {
56 if command_code_attributes.len() > Self::MAX_SIZE {
57 error!("Failed to convert Vec<CommandCodeAttributes> into CommandCodeAttributesList, to many items (> {})", Self::MAX_SIZE);
58 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
59 }
60 Ok(CommandCodeAttributesList {
61 command_code_attributes,
62 })
63 }
64}
65
66impl IntoIterator for CommandCodeAttributesList {
67 type Item = CommandCodeAttributes;
68 type IntoIter = std::vec::IntoIter<Self::Item>;
69
70 fn into_iter(self) -> Self::IntoIter {
71 self.command_code_attributes.into_iter()
72 }
73}
74
75impl TryFrom<TPML_CCA> for CommandCodeAttributesList {
76 type Error = Error;
77
78 fn try_from(tpml_cca: TPML_CCA) -> Result<Self> {
79 let count = usize::try_from(tpml_cca.count).map_err(|e| {
80 error!("Failed to parse count in TPML_CCA as usize: {}", e);
81 Error::local_error(WrapperErrorKind::InvalidParam)
82 })?;
83
84 if count > Self::MAX_SIZE {
85 error!("Invalid size value in TPML_CCA (> {})", Self::MAX_SIZE,);
86 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
87 }
88
89 tpml_cca.commandAttributes[..count]
90 .iter()
91 .map(|&tp| CommandCodeAttributes::try_from(tp))
92 .collect::<Result<Vec<CommandCodeAttributes>>>()
93 .map(|command_code_attributes| CommandCodeAttributesList {
94 command_code_attributes,
95 })
96 }
97}
98
99impl From<CommandCodeAttributesList> for TPML_CCA {
100 fn from(command_code_attributes_list: CommandCodeAttributesList) -> Self {
101 let mut tpml_cca: TPML_CCA = Default::default();
102 for command_code_attributes in command_code_attributes_list {
103 tpml_cca.commandAttributes[tpml_cca.count as usize] = command_code_attributes.into();
104 tpml_cca.count += 1;
105 }
106 tpml_cca
107 }
108}