@@ -113,6 +113,33 @@ impl<'a> Arguments<'a> {
113
113
/// Arguments structure. The compiler inserts an `unsafe` block to call this,
114
114
/// which is valid because the compiler performs all necessary validation to
115
115
/// 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) ]
116
143
#[ doc( hidden) ] #[ inline]
117
144
pub unsafe fn new < ' a > ( fmt : & ' static [ rt:: Piece < ' static > ] ,
118
145
args : & ' a [ Argument < ' a > ] ) -> Arguments < ' a > {
@@ -129,6 +156,20 @@ impl<'a> Arguments<'a> {
129
156
/// and pass it to a function or closure, passed as the first argument. The
130
157
/// macro validates the format string at compile-time so usage of the `write`
131
158
/// 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) ]
132
173
pub struct Arguments < ' a > {
133
174
fmt : & ' a [ rt:: Piece < ' a > ] ,
134
175
args : & ' a [ Argument < ' a > ] ,
@@ -255,6 +296,18 @@ uniform_fn_call_workaround! {
255
296
secret_upper_exp, UpperExp ;
256
297
}
257
298
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
+
258
311
/// The `write` function takes an output stream, a precompiled format string,
259
312
/// and a list of arguments. The arguments will be formatted according to the
260
313
/// specified format string into the output stream provided.
@@ -263,6 +316,51 @@ uniform_fn_call_workaround! {
263
316
///
264
317
/// * output - the buffer to write output to
265
318
/// * 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) ]
266
364
pub fn write ( output : & mut FormatWriter , args : & Arguments ) -> Result {
267
365
let mut formatter = Formatter {
268
366
flags : 0 ,
@@ -285,7 +383,26 @@ impl<'a> Formatter<'a> {
285
383
// First up is the collection of functions used to execute a format string
286
384
// at runtime. This consumes all of the compile-time statics generated by
287
385
// 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
+ }
288
404
405
+ #[ cfg( stage0) ] #[ doc( hidden) ]
289
406
fn run ( & mut self , piece : & rt:: Piece ) -> Result {
290
407
match * piece {
291
408
rt:: String ( s) => self . buf . write ( s. as_bytes ( ) ) ,
0 commit comments