1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

#![cfg_attr(not(any(test, feature = "std")), no_std)]

#[cfg(feature = "alloc")]
extern crate alloc;

/// Asserts that a boolean expression is true at runtime, only if debug_assertions are enabled.
///
/// Otherwise, the compiler is told to assume that the expression is always true and can perform
/// additional optimizations.
///
/// # Safety
///
/// The caller _must_ ensure this condition is never possible, otherwise the compiler
/// may optimize based on false assumptions and behave incorrectly.
#[macro_export]
macro_rules! assume {
    ($cond:expr) => {
        $crate::assume!($cond, "assumption failed: {}", stringify!($cond));
    };
    ($cond:expr $(, $fmtarg:expr)* $(,)?) => {
        let v = $cond;

        debug_assert!(v $(, $fmtarg)*);
        if cfg!(not(debug_assertions)) && !v {
            core::hint::unreachable_unchecked();
        }
    };
}

#[doc(hidden)]
#[cfg(feature = "branch-tracing")]
pub use tracing::trace as _trace;

#[cfg(not(feature = "branch-tracing"))]
#[macro_export]
#[doc(hidden)]
macro_rules! _trace {
    ($($fmt:tt)*) => {};
}

/// Traces a branch value if the `branch-tracing` feature is enabled. Otherwise it is a no-op.
#[macro_export]
macro_rules! branch {
    ($cond:expr) => {{
        let result = $cond;
        $crate::_trace!(
            branch = stringify!($cond),
            result,
            file = file!(),
            line = line!(),
        );
        result
    }};
    ($cond:expr, $outcome:expr) => {{
        let result = $cond;
        if result {
            $crate::_trace!(
                branch = stringify!($cond),
                result,
                file = file!(),
                line = line!(),
            );
        } else {
            $crate::_trace!(
                branch = stringify!($cond),
                result,
                outcome = stringify!($outcome),
                file = file!(),
                line = line!(),
            );
        }
        result
    }};
}

/// Checks that the first argument is true, otherwise returns the second value
#[macro_export]
macro_rules! ensure {
    ($cond:expr) => {
        if !$crate::branch!($cond, return) {
            return;
        }
    };
    ($cond:expr, continue) => {
        if !$crate::branch!($cond, continue) {
            continue;
        }
    };
    ($cond:expr, break $($expr:expr)?) => {
        if !$crate::branch!($cond, break $($expr)?) {
            break $($expr)?;
        }
    };
    ($cond:expr, $ret:expr) => {
        if !$crate::branch!($cond, return $ret) {
            return $ret;
        }
    };
}

/// Implements a future that wraps `T::poll_ready` and yields after ready
macro_rules! impl_ready_future {
    ($name:ident, $fut:ident, $output:ty) => {
        pub struct $fut<'a, T>(&'a mut T);

        impl<'a, T: $name> core::future::Future for $fut<'a, T> {
            type Output = $output;

            #[inline]
            fn poll(
                mut self: core::pin::Pin<&mut Self>,
                cx: &mut core::task::Context,
            ) -> core::task::Poll<Self::Output> {
                self.0.poll_ready(cx)
            }
        }
    };
}

pub mod ack;
pub mod application;
#[cfg(feature = "alloc")]
pub mod buffer;
pub mod connection;
pub mod counter;
pub mod crypto;
pub mod ct;
pub mod datagram;
pub mod endpoint;
pub mod event;
pub mod frame;
pub mod havoc;
pub mod inet;
#[cfg(feature = "alloc")]
pub mod interval_set;
pub mod io;
pub mod memo;
pub mod number;
pub mod packet;
pub mod path;
pub mod query;
pub mod random;
pub mod recovery;
pub mod slice;
pub mod stateless_reset;
pub mod stream;
pub mod sync;
pub mod task;
pub mod time;
pub mod token;
pub mod transmission;
pub mod transport;
pub mod varint;
pub mod xdp;

#[cfg(any(test, feature = "testing"))]
pub mod testing;