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}