computation_types/
arg.rs

1use core::fmt;
2use std::marker::PhantomData;
3
4use crate::{
5    impl_core_ops,
6    peano::{One, Two, Zero},
7    AnyArg, Computation, ComputationFn, NamedArgs, Names, Val,
8};
9
10#[derive(Clone, Copy, Debug)]
11pub struct Arg<Dim, T>
12where
13    Self: Computation,
14{
15    pub name: &'static str,
16    dim: PhantomData<Dim>,
17    elem: PhantomData<T>,
18}
19
20pub type Arg0<T> = Arg<Zero, T>;
21pub type Arg1<T> = Arg<One, T>;
22pub type Arg2<T> = Arg<Two, T>;
23
24impl<Dim, T> Arg<Dim, T> {
25    pub fn new(name: &'static str) -> Self {
26        Arg {
27            name,
28            dim: PhantomData,
29            elem: PhantomData,
30        }
31    }
32}
33
34#[macro_export]
35macro_rules! arg {
36    ( $name:literal ) => {
37        $crate::Arg0::new($name)
38    };
39    ( $name:literal, $elem:ty ) => {
40        $crate::Arg0::<$elem>::new($name)
41    };
42}
43
44#[macro_export]
45macro_rules! arg1 {
46    ( $name:literal ) => {
47        $crate::Arg1::new($name)
48    };
49    ( $name:literal, $elem:ty ) => {
50        $crate::Arg1::<$elem>::new($name)
51    };
52}
53
54#[macro_export]
55macro_rules! arg2 {
56    ( $name:literal ) => {
57        $crate::Arg2::new($name)
58    };
59    ( $name:literal, $elem:ty ) => {
60        $crate::Arg2::<$elem>::new($name)
61    };
62}
63
64impl<D, T> Computation for Arg<D, T> {
65    type Dim = D;
66    type Item = T;
67}
68
69impl<T> ComputationFn for Arg<Zero, T>
70where
71    Self: Computation,
72    T: 'static + AnyArg,
73{
74    type Filled = Val<Zero, T>;
75
76    fn fill(self, mut named_args: NamedArgs) -> Self::Filled {
77        Val::new(
78            named_args
79                .pop(self.name)
80                .unwrap_or_else(|e| panic!("{}", e)),
81        )
82    }
83
84    fn arg_names(&self) -> Names {
85        Names::singleton(self.name)
86    }
87}
88
89impl<T> ComputationFn for Arg<One, T>
90where
91    Self: Computation,
92    T: 'static + Clone + AnyArg,
93{
94    type Filled = Val<One, Vec<T>>;
95
96    fn fill(self, mut named_args: NamedArgs) -> Self::Filled {
97        Val::new(
98            named_args
99                .pop(self.name)
100                .unwrap_or_else(|e| panic!("{}", e)),
101        )
102    }
103
104    fn arg_names(&self) -> Names {
105        Names::singleton(self.name)
106    }
107}
108
109impl<T> ComputationFn for Arg<Two, T>
110where
111    Self: Computation,
112    T: 'static + Clone + AnyArg,
113{
114    type Filled = Val<Two, crate::run::Matrix<Vec<T>>>;
115
116    fn fill(self, mut named_args: NamedArgs) -> Self::Filled {
117        Val::new(
118            named_args
119                .pop(self.name)
120                .unwrap_or_else(|e| panic!("{}", e)),
121        )
122    }
123
124    fn arg_names(&self) -> Names {
125        Names::singleton(self.name)
126    }
127}
128
129impl_core_ops!(Arg<Dim, T>);
130
131impl<Dim, T> fmt::Display for Arg<Dim, T>
132where
133    Self: Computation,
134{
135    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136        write!(f, "{}", self.name)
137    }
138}
139
140#[cfg(test)]
141mod tests {
142    #[test]
143    fn arg_should_display_placeholder() {
144        assert_eq!(arg!("foo", i32).to_string(), "foo");
145        assert_eq!(arg1!("bar", i32).to_string(), "bar");
146    }
147}