tor_proto/circuit/
celltypes.rs1use derive_deftly::{Deftly, define_derive_deftly};
8use std::fmt::{self, Display};
9use tor_cell::chancell::BoxedCellBody;
10use tor_cell::chancell::msg::{self as chanmsg};
11use tor_cell::restricted_msg;
12
13define_derive_deftly! {
14 RestrictedChanMsgSet:
22
23 impl TryFrom<tor_cell::chancell::msg::AnyChanMsg> for $ttype {
24 type Error = $crate::Error;
25
26 fn try_from(m: tor_cell::chancell::msg::AnyChanMsg) -> $crate::Result<$ttype> {
27 match m {
28 $( tor_cell::chancell::msg::AnyChanMsg::$vname(m) => Ok($ttype::$vname(m)), )
29 _ => Err($crate::Error::ChanProto(format!(
30 "Got a {} {}",
31 <tor_cell::chancell::msg::AnyChanMsg as tor_cell::chancell::ChanMsg>::cmd(&m),
32 ${tmeta(usage) as str},
33 ))),
34 }
35 }
36 }
37
38 impl From<$ttype> for tor_cell::chancell::msg::AnyChanMsg {
39 fn from(m: $ttype) -> tor_cell::chancell::msg::AnyChanMsg {
40 match m {
41 $( $ttype::$vname(m) => m.into(), )
42 }
43 }
44 }
45}
46
47pub(crate) use derive_deftly_template_RestrictedChanMsgSet;
48
49restricted_msg! {
50 #[derive(Debug)]
52 #[allow(clippy::exhaustive_enums)]
53 pub(crate) enum CreateRequest : ChanMsg {
54 CreateFast,
55 Create2,
56 }
57}
58
59#[cfg_attr(docsrs, doc(cfg(feature = "testing")))]
62#[derive(Debug, Deftly)]
63#[allow(unreachable_pub)] #[allow(clippy::exhaustive_enums)]
65#[derive_deftly(RestrictedChanMsgSet)]
66#[deftly(usage = "in response to circuit creation")]
67pub enum CreateResponse {
68 Destroy(chanmsg::Destroy),
70 CreatedFast(chanmsg::CreatedFast),
72 Created2(chanmsg::Created2),
74}
75
76impl Display for CreateResponse {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 use CreateResponse as CR;
79 match self {
80 CR::Destroy(destroy) => write!(f, "DESTROY({})", destroy.reason()),
81 CR::CreatedFast(_) => Display::fmt("CREATED_FAST", f),
82 CR::Created2(_) => Display::fmt("CREATED2", f),
83 }
84 }
85}
86
87restricted_msg! {
88 #[derive(Debug)]
90 pub(crate) enum RelayMaybeEarlyChanMsg : ChanMsg {
91 Relay,
92 RelayEarly,
93 }
94}
95
96impl RelayMaybeEarlyChanMsg {
97 pub(crate) fn into_relay_body(self) -> BoxedCellBody {
99 match self {
100 Self::Relay(x) => x.into_relay_body(),
101 Self::RelayEarly(x) => x.into_relay_body(),
102 }
103 }
104}
105
106#[cfg(test)]
107mod test {
108 #![allow(clippy::bool_assert_comparison)]
110 #![allow(clippy::clone_on_copy)]
111 #![allow(clippy::dbg_macro)]
112 #![allow(clippy::mixed_attributes_style)]
113 #![allow(clippy::print_stderr)]
114 #![allow(clippy::print_stdout)]
115 #![allow(clippy::single_char_pattern)]
116 #![allow(clippy::unwrap_used)]
117 #![allow(clippy::unchecked_time_subtraction)]
118 #![allow(clippy::useless_vec)]
119 #![allow(clippy::needless_pass_by_value)]
120 #![allow(clippy::string_slice)] use super::*;
124
125 #[test]
126 fn create_response() {
127 use tor_cell::chancell::msg::{self, AnyChanMsg};
128 fn good(m: AnyChanMsg) {
129 assert!(CreateResponse::try_from(m).is_ok());
130 }
131 fn bad(m: AnyChanMsg) {
132 assert!(CreateResponse::try_from(m).is_err());
133 }
134
135 good(msg::Destroy::new(2.into()).into());
136 good(msg::CreatedFast::new(&b"this offer is unrepeatable"[..]).into());
137 good(msg::Created2::new(&b"guaranteed guaranteed"[..]).into());
138 bad(msg::CreateFast::new(&b"for a lifetime or more"[..]).into());
139 bad(msg::Versions::new([1, 2, 3]).unwrap().into());
140 }
141}