fn_ptr/
build.rs

1use crate::{FnPtr, Tuple, abi::Rust, safety::Safe};
2
3/// Constructs a function-pointer type from its components.
4///
5/// Given
6/// - a tuple of argument types (`Self`)
7/// - a safety marker ([`Safety`](crate::safety::Safety))
8/// - an abi ([`Abi`](crate::abi::Abi))
9/// - an output type (`Output`)
10///
11/// The trait is implemented for tuples, which get turned into the parameter types of [`F`](BuildFn::F).
12///
13/// # Examples
14///
15/// ```rust
16/// use fn_ptr::{BuildFn, safety, abi};
17/// type F0 = <(i32,) as BuildFn>::F; // fn(i32)
18/// type F1 = <() as BuildFn<safety::Unsafe, abi::Rust, u64>>::F; // unsafe fn() -> u64
19/// type F2 = <(String, f32) as BuildFn<safety::Safe, abi::C, i32>>::F; // extern "C" fn(String, f32) -> i32
20/// ```
21pub trait BuildFn<Safety = Safe, Abi = Rust, Output = ()>: Tuple {
22    /// The resulting function-pointer type.
23    type F: FnPtr<Args = Self, Output = Output, Safety = Safety, Abi = Abi>;
24}
25
26/*
27These blanket impls could replace a large portion of impl.rs but would lead to
28additional bounds when using the traits.
29
30impl<G: FnPtr, Args: BuildFn<G::Safety, G::Abi, G::Output>> WithArgs<Args> for G {
31    type F = <Args as BuildFn<G::Safety, G::Abi, G::Output>>::F;
32}
33
34impl<Output, G: FnPtr> WithOutput<Output> for G
35where
36    G::Args: BuildFn<G::Safety, G::Abi, Output>,
37{
38    type F = <G::Args as BuildFn<G::Safety, G::Abi, Output>>::F;
39}
40
41impl<Safety: safety::Safety, G: FnPtr> WithSafety<Safety> for G
42where
43    G::Args: BuildFn<Safety, G::Abi, G::Output>,
44{
45    type F = <G::Args as BuildFn<Safety, G::Abi, G::Output>>::F;
46}
47
48impl<Abi: abi::Abi, G: FnPtr> WithAbi<Abi> for G
49where
50    G::Args: BuildFn<G::Safety, Abi, G::Output>,
51{
52    type F = <G::Args as BuildFn<G::Safety, Abi, G::Output>>::F;
53}
54*/