@@ -63,7 +63,7 @@ pub enum MountRole {
6363 Scratch ,
6464}
6565
66- enum IoSpec {
66+ pub enum IoSpec {
6767 InputDir ( PathBuf ) ,
6868 InputDirOption ( String ) ,
6969}
@@ -76,8 +76,8 @@ pub struct ContainerRunSpec {
7676
7777pub struct NativeRunSpec {
7878 pub pixi : Cow < ' static , str > ,
79+ pub io_spec : IoSpec ,
7980 pub args : Vec < String > ,
80- //pub io_spec: IoSpec,
8181}
8282
8383pub struct RunSpec {
@@ -93,6 +93,30 @@ impl ContainerRunSpec {
9393 mounts : HashMap :: new ( ) ,
9494 }
9595 }
96+ pub fn with_prefixed_args < I1 , I2 , S1 , S2 > (
97+ image : impl Into < String > ,
98+ prefixes : I1 ,
99+ args : I2 ,
100+ ) -> Self
101+ where
102+ I1 : IntoIterator < Item = S1 > ,
103+ I2 : IntoIterator < Item = S2 > ,
104+ S1 : Into < String > ,
105+ S2 : Into < String > ,
106+ {
107+ let full_args: Vec < String > = prefixes
108+ . into_iter ( )
109+ . map ( Into :: into)
110+ . chain ( args. into_iter ( ) . map ( Into :: into) )
111+ . collect ( ) ;
112+
113+ Self {
114+ image : Image ( image. into ( ) ) ,
115+ args : full_args,
116+ mounts : HashMap :: new ( ) ,
117+ }
118+ }
119+
96120 pub fn scratch ( mut self , p : impl Into < String > ) -> Self {
97121 self . mounts . insert ( MountRole :: Scratch , p. into ( ) ) ;
98122 self
@@ -104,16 +128,17 @@ impl ContainerRunSpec {
104128}
105129
106130impl NativeRunSpec {
107- pub fn new ( pixi : impl Into < Cow < ' static , str > > , args : Vec < String > ) -> Self {
131+ pub fn new ( pixi : impl Into < Cow < ' static , str > > , io_spec : IoSpec , args : Vec < String > ) -> Self {
108132 Self {
109133 pixi : pixi. into ( ) ,
134+ io_spec,
110135 args,
111136 }
112137 }
113- pub fn pixi ( mut self , p : impl Into < Cow < ' static , str > > ) -> Self {
114- self . pixi = p. into ( ) ;
115- self
116- }
138+ // pub fn pixi(mut self, p: impl Into<Cow<'static, str>>) -> Self {
139+ // self.pixi = p.into();
140+ // self
141+ // }
117142}
118143
119144impl RunSpec {
@@ -136,3 +161,62 @@ impl App {
136161 }
137162 }
138163}
164+
165+ #[ cfg( test) ]
166+ mod tests {
167+ use super :: * ;
168+
169+ #[ test]
170+ fn test_with_prefixed_args ( ) {
171+ let prefixes = vec ! [ "--prefix1" , "--prefix2" ] ;
172+ let args = vec ! [ "arg1" , "arg2" , "arg3" ] ;
173+
174+ let spec = ContainerRunSpec :: with_prefixed_args (
175+ "test/image:latest" ,
176+ prefixes. clone ( ) ,
177+ args. clone ( ) ,
178+ ) ;
179+
180+ assert_eq ! ( spec. image. 0 , "test/image:latest" ) ;
181+ assert_eq ! (
182+ spec. args,
183+ vec![ "--prefix1" , "--prefix2" , "arg1" , "arg2" , "arg3" ]
184+ ) ;
185+ assert_eq ! ( spec. mounts. len( ) , 0 ) ;
186+ }
187+
188+ #[ test]
189+ fn test_with_prefixed_args_empty_prefixes ( ) {
190+ let prefixes: Vec < String > = vec ! [ ] ;
191+ let args = vec ! [ "arg1" . to_string( ) , "arg2" . to_string( ) ] ;
192+
193+ let spec = ContainerRunSpec :: with_prefixed_args ( "test/image:v1" , prefixes, args. clone ( ) ) ;
194+
195+ assert_eq ! ( spec. image. 0 , "test/image:v1" ) ;
196+ assert_eq ! ( spec. args, vec![ "arg1" , "arg2" ] ) ;
197+ }
198+
199+ #[ test]
200+ fn test_with_prefixed_args_empty_args ( ) {
201+ let prefixes = vec ! [ "--flag" . to_string( ) ] ;
202+ let args: Vec < String > = vec ! [ ] ;
203+
204+ let spec = ContainerRunSpec :: with_prefixed_args ( "test/image" , prefixes. clone ( ) , args) ;
205+
206+ assert_eq ! ( spec. image. 0 , "test/image" ) ;
207+ assert_eq ! ( spec. args. len( ) , 1 ) ;
208+ assert_eq ! ( spec. args[ 0 ] , "--flag" ) ;
209+ }
210+
211+ #[ test]
212+ fn test_with_prefixed_args_both_empty ( ) {
213+ let prefixes: Vec < String > = vec ! [ ] ;
214+ let args: Vec < String > = vec ! [ ] ;
215+
216+ let spec = ContainerRunSpec :: with_prefixed_args ( "empty/image" , prefixes, args) ;
217+
218+ assert_eq ! ( spec. image. 0 , "empty/image" ) ;
219+ assert_eq ! ( spec. args. len( ) , 0 ) ;
220+ assert ! ( spec. mounts. is_empty( ) ) ;
221+ }
222+ }
0 commit comments