@@ -113,6 +113,33 @@ impl<'a> Arguments<'a> {
113113 /// Arguments structure. The compiler inserts an `unsafe` block to call this,
114114 /// which is valid because the compiler performs all necessary validation to
115115 /// ensure that the resulting call to format/write would be safe.
116+ #[ cfg( not( stage0) ) ]
117+ #[ doc( hidden) ] #[ inline]
118+ pub unsafe fn new < ' a > ( pieces : & ' static [ & ' static str ] ,
119+ args : & ' a [ Argument < ' a > ] ) -> Arguments < ' a > {
120+ Arguments {
121+ pieces : mem:: transmute ( pieces) ,
122+ fmt : None ,
123+ args : args
124+ }
125+ }
126+
127+ /// This function is used to specify nonstandard formatting parameters.
128+ /// The `pieces` array must be at least as long as `fmt` to construct
129+ /// a valid Arguments structure.
130+ #[ cfg( not( stage0) ) ]
131+ #[ doc( hidden) ] #[ inline]
132+ pub unsafe fn with_placeholders < ' a > ( pieces : & ' static [ & ' static str ] ,
133+ fmt : & ' static [ rt:: Argument < ' static > ] ,
134+ args : & ' a [ Argument < ' a > ] ) -> Arguments < ' a > {
135+ Arguments {
136+ pieces : mem:: transmute ( pieces) ,
137+ fmt : Some ( mem:: transmute ( fmt) ) ,
138+ args : args
139+ }
140+ }
141+
142+ #[ cfg( stage0) ]
116143 #[ doc( hidden) ] #[ inline]
117144 pub unsafe fn new < ' a > ( fmt : & ' static [ rt:: Piece < ' static > ] ,
118145 args : & ' a [ Argument < ' a > ] ) -> Arguments < ' a > {
@@ -129,6 +156,20 @@ impl<'a> Arguments<'a> {
129156/// and pass it to a function or closure, passed as the first argument. The
130157/// macro validates the format string at compile-time so usage of the `write`
131158/// and `format` functions can be safely performed.
159+ #[ cfg( not( stage0) ) ]
160+ pub struct Arguments < ' a > {
161+ // Format string pieces to print.
162+ pieces : & ' a [ & ' a str ] ,
163+
164+ // Placeholder specs, or `None` if all specs are default (as in "{}{}").
165+ fmt : Option < & ' a [ rt:: Argument < ' a > ] > ,
166+
167+ // Dynamic arguments for interpolation, to be interleaved with string
168+ // pieces. (Every argument is preceded by a string piece.)
169+ args : & ' a [ Argument < ' a > ] ,
170+ }
171+
172+ #[ cfg( stage0) ] #[ doc( hidden) ]
132173pub struct Arguments < ' a > {
133174 fmt : & ' a [ rt:: Piece < ' a > ] ,
134175 args : & ' a [ Argument < ' a > ] ,
@@ -255,6 +296,18 @@ uniform_fn_call_workaround! {
255296 secret_upper_exp, UpperExp ;
256297}
257298
299+ #[ cfg( not( stage0) ) ]
300+ static DEFAULT_ARGUMENT : rt:: Argument < ' static > = rt:: Argument {
301+ position : rt:: ArgumentNext ,
302+ format : rt:: FormatSpec {
303+ fill : ' ' ,
304+ align : rt:: AlignUnknown ,
305+ flags : 0 ,
306+ precision : rt:: CountImplied ,
307+ width : rt:: CountImplied ,
308+ }
309+ } ;
310+
258311/// The `write` function takes an output stream, a precompiled format string,
259312/// and a list of arguments. The arguments will be formatted according to the
260313/// specified format string into the output stream provided.
@@ -263,6 +316,51 @@ uniform_fn_call_workaround! {
263316///
264317/// * output - the buffer to write output to
265318/// * args - the precompiled arguments generated by `format_args!`
319+ #[ cfg( not( stage0) ) ]
320+ pub fn write ( output : & mut FormatWriter , args : & Arguments ) -> Result {
321+ let mut formatter = Formatter {
322+ flags : 0 ,
323+ width : None ,
324+ precision : None ,
325+ buf : output,
326+ align : rt:: AlignUnknown ,
327+ fill : ' ' ,
328+ args : args. args ,
329+ curarg : args. args . iter ( ) ,
330+ } ;
331+
332+ let mut pieces = args. pieces . iter ( ) ;
333+
334+ match args. fmt {
335+ None => {
336+ // We can use default formatting parameters for all arguments.
337+ for _ in range ( 0 , args. args . len ( ) ) {
338+ try!( formatter. buf . write ( pieces. next ( ) . unwrap ( ) . as_bytes ( ) ) ) ;
339+ try!( formatter. run ( & DEFAULT_ARGUMENT ) ) ;
340+ }
341+ }
342+ Some ( fmt) => {
343+ // Every spec has a corresponding argument that is preceded by
344+ // a string piece.
345+ for ( arg, piece) in fmt. iter ( ) . zip ( pieces. by_ref ( ) ) {
346+ try!( formatter. buf . write ( piece. as_bytes ( ) ) ) ;
347+ try!( formatter. run ( arg) ) ;
348+ }
349+ }
350+ }
351+
352+ // There can be only one trailing string piece left.
353+ match pieces. next ( ) {
354+ Some ( piece) => {
355+ try!( formatter. buf . write ( piece. as_bytes ( ) ) ) ;
356+ }
357+ None => { }
358+ }
359+
360+ Ok ( ( ) )
361+ }
362+
363+ #[ cfg( stage0) ] #[ doc( hidden) ]
266364pub fn write ( output : & mut FormatWriter , args : & Arguments ) -> Result {
267365 let mut formatter = Formatter {
268366 flags : 0 ,
@@ -285,7 +383,26 @@ impl<'a> Formatter<'a> {
285383 // First up is the collection of functions used to execute a format string
286384 // at runtime. This consumes all of the compile-time statics generated by
287385 // the format! syntax extension.
386+ #[ cfg( not( stage0) ) ]
387+ fn run ( & mut self , arg : & rt:: Argument ) -> Result {
388+ // Fill in the format parameters into the formatter
389+ self . fill = arg. format . fill ;
390+ self . align = arg. format . align ;
391+ self . flags = arg. format . flags ;
392+ self . width = self . getcount ( & arg. format . width ) ;
393+ self . precision = self . getcount ( & arg. format . precision ) ;
394+
395+ // Extract the correct argument
396+ let value = match arg. position {
397+ rt:: ArgumentNext => { * self . curarg . next ( ) . unwrap ( ) }
398+ rt:: ArgumentIs ( i) => self . args [ i] ,
399+ } ;
400+
401+ // Then actually do some printing
402+ ( value. formatter ) ( value. value , self )
403+ }
288404
405+ #[ cfg( stage0) ] #[ doc( hidden) ]
289406 fn run ( & mut self , piece : & rt:: Piece ) -> Result {
290407 match * piece {
291408 rt:: String ( s) => self . buf . write ( s. as_bytes ( ) ) ,
0 commit comments