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
use crate::Packet;
use bytes::Bytes;
use std::fmt::Debug;
use std::ops::Deref;
use std::sync::Arc;

pub(crate) type DynCallback<I> = dyn Fn(I) + 'static + Sync + Send;

#[derive(Clone)]
/// Internal type, only implements debug on fixed set of generics
pub(crate) struct OptionalCallback<I> {
    inner: Arc<Option<Box<DynCallback<I>>>>,
}

impl<I> OptionalCallback<I> {
    pub(crate) fn new<T>(callback: T) -> Self
    where
        T: Fn(I) + 'static + Sync + Send,
    {
        OptionalCallback {
            inner: Arc::new(Some(Box::new(callback))),
        }
    }

    pub(crate) fn default() -> Self {
        OptionalCallback {
            inner: Arc::new(None),
        }
    }
}

#[cfg_attr(tarpaulin, ignore)]
impl Debug for OptionalCallback<String> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        f.write_fmt(format_args!(
            "Callback({:?})",
            if self.inner.is_some() {
                "Fn(String)"
            } else {
                "None"
            }
        ))
    }
}

#[cfg_attr(tarpaulin, ignore)]
impl Debug for OptionalCallback<()> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        f.write_fmt(format_args!(
            "Callback({:?})",
            if self.inner.is_some() {
                "Fn(())"
            } else {
                "None"
            }
        ))
    }
}

#[cfg_attr(tarpaulin, ignore)]
impl Debug for OptionalCallback<Packet> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        f.write_fmt(format_args!(
            "Callback({:?})",
            if self.inner.is_some() {
                "Fn(Packet)"
            } else {
                "None"
            }
        ))
    }
}

#[cfg_attr(tarpaulin, ignore)]
impl Debug for OptionalCallback<Bytes> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        f.write_fmt(format_args!(
            "Callback({:?})",
            if self.inner.is_some() {
                "Fn(Bytes)"
            } else {
                "None"
            }
        ))
    }
}

impl<I> Deref for OptionalCallback<I> {
    type Target = Option<Box<DynCallback<I>>>;
    fn deref(&self) -> &<Self as std::ops::Deref>::Target {
        self.inner.as_ref()
    }
}