tss_esapi/structures/lists/
command_code.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    constants::CommandCode,
6    tss2_esys::{TPM2_MAX_CAP_CC, TPML_CC},
7    Error, Result, WrapperErrorKind,
8};
9use log::error;
10use std::{convert::TryFrom, ops::Deref};
11
12/// A list of command codes.
13#[derive(Debug, Clone, Default)]
14pub struct CommandCodeList {
15    command_codes: Vec<CommandCode>,
16}
17
18impl CommandCodeList {
19    pub const MAX_SIZE: usize = Self::calculate_max_size();
20    /// Creates a new CommandCodeList
21    pub const fn new() -> Self {
22        CommandCodeList {
23            command_codes: Vec::new(),
24        }
25    }
26
27    /// Adds a command code to the command code list.
28    pub fn add(&mut self, command_code: CommandCode) -> Result<()> {
29        if self.command_codes.len() + 1 > CommandCodeList::MAX_SIZE {
30            error!(
31                "Adding command code to list will make the list exceeded its maximum count(> {})",
32                CommandCodeList::MAX_SIZE
33            );
34            return Err(Error::local_error(WrapperErrorKind::WrongParamSize));
35        }
36        self.command_codes.push(command_code);
37        Ok(())
38    }
39
40    /// Returns the inner type.
41    pub fn into_inner(self) -> Vec<CommandCode> {
42        self.command_codes
43    }
44
45    /// Private function that calculates the maximum number
46    /// elements allowed in internal storage.
47    const fn calculate_max_size() -> usize {
48        TPM2_MAX_CAP_CC as usize
49    }
50}
51
52impl TryFrom<TPML_CC> for CommandCodeList {
53    type Error = Error;
54
55    fn try_from(tpml_cc: TPML_CC) -> Result<Self> {
56        let command_code_count = tpml_cc.count as usize;
57        if command_code_count > Self::MAX_SIZE {
58            error!("Error: Invalid TPML_CC count(> {})", Self::MAX_SIZE);
59            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
60        }
61        tpml_cc.commandCodes[..command_code_count]
62            .iter()
63            .map(|&cc| CommandCode::try_from(cc))
64            .collect::<Result<Vec<CommandCode>>>()
65            .map(|command_codes| CommandCodeList { command_codes })
66    }
67}
68
69impl From<CommandCodeList> for TPML_CC {
70    fn from(command_code_list: CommandCodeList) -> Self {
71        let mut tpml_cc = TPML_CC::default();
72        for cc in command_code_list.command_codes {
73            tpml_cc.commandCodes[tpml_cc.count as usize] = cc.into();
74            tpml_cc.count += 1;
75        }
76        tpml_cc
77    }
78}
79
80impl TryFrom<Vec<CommandCode>> for CommandCodeList {
81    type Error = Error;
82
83    fn try_from(command_codes: Vec<CommandCode>) -> Result<Self> {
84        if command_codes.len() > Self::MAX_SIZE {
85            error!("Error: Invalid TPML_CC count(> {})", Self::MAX_SIZE);
86            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
87        }
88        Ok(CommandCodeList { command_codes })
89    }
90}
91
92impl From<CommandCodeList> for Vec<CommandCode> {
93    fn from(command_code_list: CommandCodeList) -> Self {
94        command_code_list.command_codes
95    }
96}
97
98impl AsRef<[CommandCode]> for CommandCodeList {
99    fn as_ref(&self) -> &[CommandCode] {
100        self.command_codes.as_slice()
101    }
102}
103
104impl Deref for CommandCodeList {
105    type Target = Vec<CommandCode>;
106
107    fn deref(&self) -> &Self::Target {
108        &self.command_codes
109    }
110}