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}