typed_floats_macros/
try_from.rs

1use quote::quote;
2
3use crate::types::FloatDefinition;
4
5fn impl_from(float_from: &FloatDefinition, float_to: &FloatDefinition) -> proc_macro2::TokenStream {
6    let from_full_type = &float_from.full_type_ident();
7    let to_full_type = &float_to.full_type_ident();
8
9    quote! {
10        impl core::convert::From<#from_full_type> for #to_full_type {
11            #[inline]
12            #[must_use]
13            fn from(value: #from_full_type) -> Self {
14                unsafe { Self::new_unchecked(value.get()) }
15            }
16        }
17    }
18}
19
20fn impl_try_from(
21    float_from: &FloatDefinition,
22    float_to: &FloatDefinition,
23) -> proc_macro2::TokenStream {
24    let from_full_type = &float_from.full_type_ident();
25    let to_full_type = &float_to.full_type_ident();
26
27    quote! {
28        impl core::convert::TryFrom<#from_full_type> for #to_full_type {
29            type Error = InvalidNumber;
30
31            #[inline]
32            #[must_use]
33            fn try_from(value: #from_full_type) -> Result<Self, Self::Error> {
34                Self::try_from(value.get())
35            }
36        }
37    }
38}
39
40pub fn impl_from_or_try_from(
41    float_from: &FloatDefinition,
42    float_to: &FloatDefinition,
43) -> proc_macro2::TokenStream {
44    let from = &float_from.s;
45    let to = &float_to.s;
46
47    if (!from.accept_positive && to.accept_negative)
48        && (!from.accept_negative && to.accept_positive)
49    {
50        // No conversion between positive and negative
51        proc_macro2::TokenStream::new()
52    } else if from.can_fit_into(to) {
53        impl_from(float_from, float_to)
54    } else {
55        impl_try_from(float_from, float_to)
56    }
57}