1use crate::{algorithm::Algorithm, capability::Capability, client, domain::Domain, object};
4use std::io::Write;
5
6#[cfg(feature = "mockhsm")]
7use {
8 crate::{client::ErrorKind::ProtocolError, object::LABEL_SIZE},
9 std::io::Read,
10};
11
12pub enum Filter {
14 Algorithm(Algorithm),
16
17 Capabilities(Capability),
19
20 Domains(Domain),
22
23 Label(object::Label),
25
26 Id(object::Id),
28
29 Type(object::Type),
31}
32
33#[cfg(feature = "mockhsm")]
34macro_rules! read_byte {
35 ($reader:expr) => {{
36 let mut byte = [0u8];
37 $reader.read_exact(&mut byte)?;
38 byte[0]
39 }};
40}
41
42#[cfg(feature = "mockhsm")]
43macro_rules! read_be_bytes {
44 ($reader:expr, $type:path) => {{
45 let mut bytes = [0u8; std::mem::size_of::<$type>()];
46 $reader.read_exact(&mut bytes)?;
47 <$type>::from_be_bytes(bytes)
48 }};
49}
50
51impl Filter {
52 pub fn tag(&self) -> u8 {
54 match *self {
55 Filter::Id(_) => 0x01,
56 Filter::Type(_) => 0x02,
57 Filter::Domains(_) => 0x03,
58 Filter::Capabilities(_) => 0x04,
59 Filter::Algorithm(_) => 0x05,
60 Filter::Label(_) => 0x06,
61 }
62 }
63
64 pub(crate) fn serialize<W: Write>(&self, mut writer: W) -> Result<W, client::Error> {
66 writer.write_all(&[self.tag()])?;
67
68 match *self {
69 Filter::Algorithm(alg) => writer.write_all(&[alg.to_u8()])?,
70 Filter::Capabilities(caps) => writer.write_all(&caps.bits().to_be_bytes())?,
71 Filter::Domains(doms) => writer.write_all(&doms.bits().to_be_bytes())?,
72 Filter::Label(ref label) => {
73 writer.write_all(label.as_ref())?;
74 }
75 Filter::Id(id) => writer.write_all(&id.to_be_bytes())?,
76 Filter::Type(ty) => writer.write_all(&[ty.to_u8()])?,
77 }
78
79 Ok(writer)
80 }
81
82 #[cfg(feature = "mockhsm")]
84 pub(crate) fn deserialize<R: Read>(mut reader: R) -> Result<Self, client::Error> {
85 let tag = read_byte!(reader);
86
87 Ok(match tag {
88 0x01 => Filter::Id(read_be_bytes!(reader, u16)),
89 0x02 => Filter::Type(
90 object::Type::from_u8(read_byte!(reader))
91 .map_err(|e| format_err!(ProtocolError, e))?,
92 ),
93 0x03 => Filter::Domains(
94 Domain::from_bits(read_be_bytes!(reader, u16))
95 .ok_or_else(|| format_err!(ProtocolError, "invalid domain bitflags"))?,
96 ),
97 0x04 => Filter::Capabilities(
98 Capability::from_bits(read_be_bytes!(reader, u64))
99 .ok_or_else(|| format_err!(ProtocolError, "invalid capability bitflags"))?,
100 ),
101 0x05 => Filter::Algorithm(
102 Algorithm::from_u8(read_byte!(reader))
103 .map_err(|e| format_err!(ProtocolError, e))?,
104 ),
105 0x06 => {
106 let mut label_bytes = [0u8; LABEL_SIZE];
107 reader.read_exact(&mut label_bytes)?;
108 Filter::Label(object::Label(label_bytes))
109 }
110 _ => fail!(ProtocolError, "invalid filter tag: 0x{:2x}", tag),
111 })
112 }
113}