#[cfg(feature = "mockhsm")]
use byteorder::ReadBytesExt;
use byteorder::{WriteBytesExt, BE};
#[cfg(feature = "mockhsm")]
use std::io::Read;
use std::io::Write;
use super::ClientError;
#[cfg(feature = "mockhsm")]
use super::ClientErrorKind::ProtocolError;
use crate::algorithm::Algorithm;
use crate::capability::Capability;
use crate::command::{Command, CommandCode};
use crate::domain::Domain;
#[cfg(feature = "mockhsm")]
use crate::object::LABEL_SIZE;
use crate::object::{ObjectId, ObjectLabel, ObjectType, SequenceId};
use crate::response::Response;
#[derive(Serialize, Deserialize, Debug)]
pub(crate) struct ListObjectsCommand(pub(crate) Vec<u8>);
impl Command for ListObjectsCommand {
type ResponseType = ListObjectsResponse;
}
#[derive(Serialize, Deserialize, Debug)]
pub(crate) struct ListObjectsResponse(pub(crate) Vec<ListObjectsEntry>);
impl Response for ListObjectsResponse {
const COMMAND_CODE: CommandCode = CommandCode::ListObjects;
}
pub enum Filter {
Algorithm(Algorithm),
Capabilities(Capability),
Domains(Domain),
Label(ObjectLabel),
Id(ObjectId),
Type(ObjectType),
}
impl Filter {
pub fn tag(&self) -> u8 {
match *self {
Filter::Id(_) => 0x01,
Filter::Type(_) => 0x02,
Filter::Domains(_) => 0x03,
Filter::Capabilities(_) => 0x04,
Filter::Algorithm(_) => 0x05,
Filter::Label(_) => 0x06,
}
}
pub(crate) fn serialize<W: Write>(&self, mut writer: W) -> Result<W, ClientError> {
writer.write_u8(self.tag())?;
match *self {
Filter::Algorithm(alg) => writer.write_u8(alg.to_u8())?,
Filter::Capabilities(caps) => writer.write_u64::<BE>(caps.bits())?,
Filter::Domains(doms) => writer.write_u16::<BE>(doms.bits())?,
Filter::Label(ref label) => {
writer.write_all(label.as_ref())?;
}
Filter::Id(id) => writer.write_u16::<BE>(id)?,
Filter::Type(ty) => writer.write_u8(ty.to_u8())?,
}
Ok(writer)
}
#[cfg(feature = "mockhsm")]
pub(crate) fn deserialize<R: Read>(mut reader: R) -> Result<Self, ClientError> {
let tag = reader.read_u8()?;
Ok(match tag {
0x01 => Filter::Id(reader.read_u16::<BE>()?),
0x02 => Filter::Type(
ObjectType::from_u8(reader.read_u8()?).map_err(|e| err!(ProtocolError, e))?,
),
0x03 => Filter::Domains(
Domain::from_bits(reader.read_u16::<BE>()?)
.ok_or_else(|| err!(ProtocolError, "invalid domain bitflags"))?,
),
0x04 => Filter::Capabilities(
Capability::from_bits(reader.read_u64::<BE>()?)
.ok_or_else(|| err!(ProtocolError, "invalid capability bitflags"))?,
),
0x05 => Filter::Algorithm(
Algorithm::from_u8(reader.read_u8()?).map_err(|e| err!(ProtocolError, e))?,
),
0x06 => {
let mut label_bytes = [0u8; LABEL_SIZE];
reader.read_exact(&mut label_bytes)?;
Filter::Label(ObjectLabel(label_bytes))
}
_ => fail!(ProtocolError, "invalid filter tag: 0x{:2x}", tag),
})
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct ListObjectsEntry {
pub object_id: ObjectId,
pub object_type: ObjectType,
pub sequence: SequenceId,
}