1use std::ops::Deref;
8
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
15pub enum Proxy<T> {
16 No,
18 #[default]
20 System,
21 Custom(T),
23}
24
25impl<T> Proxy<T> {
26 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Proxy<U> {
29 match self {
30 Self::No => Proxy::No,
31 Self::System => Proxy::System,
32 Self::Custom(t) => Proxy::Custom(f(t)),
33 }
34 }
35
36 pub fn as_deref(&self) -> Proxy<&T::Target>
39 where
40 T: Deref,
41 {
42 match self {
43 Self::No => Proxy::No,
44 Self::System => Proxy::System,
45 Self::Custom(t) => Proxy::Custom(&**t),
46 }
47 }
48
49 pub const fn as_ref(&self) -> Proxy<&T> {
52 match self {
53 Self::No => Proxy::No,
54 Self::System => Proxy::System,
55 Self::Custom(t) => Proxy::Custom(t),
56 }
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn map_transforms_custom_only() {
66 assert_eq!(Proxy::<i32>::No.map(|x| x + 1), Proxy::No);
67 assert_eq!(Proxy::<i32>::System.map(|x| x + 1), Proxy::System);
68 assert_eq!(Proxy::Custom(5).map(|x| x + 1), Proxy::Custom(6));
69 }
70
71 #[test]
72 fn as_deref_borrows_custom() {
73 let p: Proxy<String> = Proxy::Custom("http".to_string());
74 assert_eq!(p.as_deref(), Proxy::Custom("http"));
75 assert_eq!(Proxy::<String>::No.as_deref(), Proxy::No);
76 assert_eq!(Proxy::<String>::System.as_deref(), Proxy::System);
77 }
78
79 #[test]
80 fn as_ref_borrows_custom() {
81 let p: Proxy<i32> = Proxy::Custom(7);
82 assert_eq!(p.as_ref(), Proxy::Custom(&7));
83 assert_eq!(Proxy::<i32>::No.as_ref(), Proxy::No);
84 assert_eq!(Proxy::<i32>::System.as_ref(), Proxy::System);
85 }
86
87 #[test]
88 fn default_is_system() {
89 assert_eq!(Proxy::<String>::default(), Proxy::System);
90 }
91
92 #[test]
93 fn copy_and_equality() {
94 let p = Proxy::Custom(3);
95 let q = p; assert_eq!(p, q);
97 }
98}