rama_core/conversion.rs
1/// Alternative for [`From`] which can be implemented by external crates for external types
2///
3/// To implement this trait, use a crate local `CrateMarker` generic type
4/// More info: <https://ramaproxy.org/book/intro/patterns.html#working-around-the-orphan-rule-in-specific-cases>
5///
6/// Note: [`RamaFrom`] has a blacket implementation for types that implement [`From`]
7pub trait RamaFrom<T, CrateMarker = ()> {
8 fn rama_from(value: T) -> Self;
9}
10
11impl<T, U> RamaFrom<T> for U
12where
13 U: From<T>,
14{
15 fn rama_from(value: T) -> Self {
16 Self::from(value)
17 }
18}
19
20/// Alternative for [`Into`] which can be implemented by external crates for external types
21///
22/// To implement this trait, use a crate local `CrateMarker` generic type
23/// More info: <https://ramaproxy.org/book/intro/patterns.html#working-around-the-orphan-rule-in-specific-cases>
24///
25/// Note: [`RamaInto`] has a blacket implementation for types that implement [`RamaFrom`] in
26/// the opposite direction, and as such also work for types that implement [`Into`]
27pub trait RamaInto<T, CrateMarker = ()>: Sized {
28 fn rama_into(self) -> T;
29}
30
31impl<T, U, CrateMarker> RamaInto<U, CrateMarker> for T
32where
33 U: RamaFrom<T, CrateMarker>,
34{
35 #[inline(always)]
36 fn rama_into(self) -> U {
37 U::rama_from(self)
38 }
39}
40
41/// Alternative for [`TryFrom`] which can be implemented by external crates for external types
42///
43/// To implement this trait, use a crate local `CrateMarker` generic type
44/// More info: <https://ramaproxy.org/book/intro/patterns.html#working-around-the-orphan-rule-in-specific-cases>
45///
46/// Note: [`RamaTryFrom`] has a blacket implementation for types that implement [`TryFrom`]
47pub trait RamaTryFrom<T, CrateMarker = ()>: Sized {
48 type Error;
49 fn rama_try_from(value: T) -> Result<Self, Self::Error>;
50}
51
52impl<T, U> RamaTryFrom<T> for U
53where
54 U: TryFrom<T>,
55{
56 type Error = U::Error;
57
58 fn rama_try_from(value: T) -> Result<Self, Self::Error> {
59 Self::try_from(value)
60 }
61}
62
63/// Alternative for [`TryInto`] which can be implemented by external crates for external types
64///
65/// To implement this trait, use a crate local `CrateMarker` generic type
66/// More info: <https://ramaproxy.org/book/intro/patterns.html#working-around-the-orphan-rule-in-specific-cases>
67///
68/// Note: [`RamaTryInto`] has a blacket implementation for types that implement [`RamaTryFrom`] in
69/// the opposite direction, and as such also work for types that implement [`TryInto`]
70pub trait RamaTryInto<T, CrateMarker = ()>: Sized {
71 type Error;
72 fn rama_try_into(self) -> Result<T, Self::Error>;
73}
74
75impl<T, U, CrateMarker> RamaTryInto<U, CrateMarker> for T
76where
77 U: RamaTryFrom<T, CrateMarker>,
78{
79 type Error = U::Error;
80
81 #[inline(always)]
82 fn rama_try_into(self) -> Result<U, U::Error> {
83 U::rama_try_from(self)
84 }
85}
86
87/// Create `Self` from a reference `T`
88///
89/// This is mostly used for extractors, but it can be used for anything
90/// that needs to create an owned type from a reference
91pub trait FromRef<T> {
92 /// Converts to this type from a reference to the input type.
93 fn from_ref(input: &T) -> Self;
94}
95
96pub use rama_macros::FromRef;
97
98impl<T> FromRef<T> for T
99where
100 T: Clone,
101{
102 fn from_ref(input: &T) -> Self {
103 input.clone()
104 }
105}