1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 use crate::*;
16
17 #[test]
test_parse()18 fn test_parse() {
19 assert_eq!(
20 FormatString::parse_printf("long double %+ 4.2Lf is %-03hd%%."),
21 Ok(FormatString {
22 fragments: vec![
23 FormatFragment::Literal("long double ".to_string()),
24 FormatFragment::Conversion(ConversionSpec {
25 argument: Argument::None,
26 fill: ' ',
27 alignment: Alignment::None,
28 flags: [Flag::ForceSign, Flag::SpaceSign].into_iter().collect(),
29 min_field_width: MinFieldWidth::Fixed(4),
30 precision: Precision::Fixed(2),
31 length: Some(Length::LongDouble),
32 primitive: Primitive::Float,
33 style: Style::None,
34 }),
35 FormatFragment::Literal(" is ".to_string()),
36 FormatFragment::Conversion(ConversionSpec {
37 argument: Argument::None,
38 fill: ' ',
39 alignment: Alignment::Left,
40 flags: [Flag::LeftJustify, Flag::LeadingZeros]
41 .into_iter()
42 .collect(),
43 min_field_width: MinFieldWidth::Fixed(3),
44 precision: Precision::None,
45 length: Some(Length::Short),
46 primitive: Primitive::Integer,
47 style: Style::None,
48 }),
49 FormatFragment::Literal("%.".to_string()),
50 ]
51 })
52 );
53 }
54
55 //
56 // The following test cases are from //pw_tokenizer/py/decode_test.py
57 //
58
59 #[test]
test_percent()60 fn test_percent() {
61 assert_eq!(
62 FormatString::parse_printf("%%"),
63 Ok(FormatString {
64 fragments: vec![FormatFragment::Literal("%".to_string())],
65 }),
66 );
67 }
68
69 #[test]
test_percent_with_leading_plus_fails()70 fn test_percent_with_leading_plus_fails() {
71 assert!(FormatString::parse_printf("%+%").is_err());
72 }
73
74 #[test]
test_percent_with_leading_negative_fails()75 fn test_percent_with_leading_negative_fails() {
76 assert!(FormatString::parse_printf("%-%").is_err());
77 }
78
79 #[test]
test_percent_with_leading_space_fails()80 fn test_percent_with_leading_space_fails() {
81 assert!(FormatString::parse_printf("% %").is_err());
82 }
83
84 #[test]
test_percent_with_leading_hash_fails()85 fn test_percent_with_leading_hash_fails() {
86 assert!(FormatString::parse_printf("%#%").is_err());
87 }
88
89 #[test]
test_percent_with_leading_zero_fails()90 fn test_percent_with_leading_zero_fails() {
91 assert!(FormatString::parse_printf("%0%").is_err());
92 }
93
94 #[test]
test_percent_with_length_fails()95 fn test_percent_with_length_fails() {
96 assert!(FormatString::parse_printf("%hh%").is_err());
97 assert!(FormatString::parse_printf("%h%").is_err());
98 assert!(FormatString::parse_printf("%l%").is_err());
99 assert!(FormatString::parse_printf("%L%").is_err());
100 assert!(FormatString::parse_printf("%j%").is_err());
101 assert!(FormatString::parse_printf("%z%").is_err());
102 assert!(FormatString::parse_printf("%t%").is_err());
103 }
104
105 #[test]
test_percent_with_width_fails()106 fn test_percent_with_width_fails() {
107 assert!(FormatString::parse_printf("%9%").is_err());
108 }
109
110 #[test]
test_percent_with_multidigit_width_fails()111 fn test_percent_with_multidigit_width_fails() {
112 assert!(FormatString::parse_printf("%10%").is_err());
113 }
114
115 #[test]
test_percent_with_star_width_fails()116 fn test_percent_with_star_width_fails() {
117 assert!(FormatString::parse_printf("%*%").is_err());
118 }
119
120 #[test]
test_percent_with_precision_fails()121 fn test_percent_with_precision_fails() {
122 assert!(FormatString::parse_printf("%.5%").is_err());
123 }
124
125 #[test]
test_percent_with_multidigit_precision_fails()126 fn test_percent_with_multidigit_precision_fails() {
127 assert!(FormatString::parse_printf("%.10%").is_err());
128 }
129
130 #[test]
test_percent_with_star_precision_fails()131 fn test_percent_with_star_precision_fails() {
132 assert!(FormatString::parse_printf("%*%").is_err());
133 }
134
135 const INTEGERS: &[(&str, Primitive, Style)] = &[
136 ("d", Primitive::Integer, Style::None),
137 ("i", Primitive::Integer, Style::None),
138 ("o", Primitive::Unsigned, Style::Octal),
139 ("u", Primitive::Unsigned, Style::None),
140 ("x", Primitive::Unsigned, Style::Hex),
141 ("X", Primitive::Unsigned, Style::UpperHex),
142 // While not strictly an integer pointers take the same args as integers.
143 ("p", Primitive::Pointer, Style::Pointer),
144 ];
145
146 #[test]
test_integer()147 fn test_integer() {
148 for (format_char, primitive, style) in INTEGERS {
149 assert_eq!(
150 FormatString::parse_printf(&format!("%{format_char}")),
151 Ok(FormatString {
152 fragments: vec![FormatFragment::Conversion(ConversionSpec {
153 argument: Argument::None,
154 fill: ' ',
155 alignment: Alignment::None,
156 flags: HashSet::new(),
157 min_field_width: MinFieldWidth::None,
158 precision: Precision::None,
159 length: None,
160 primitive: *primitive,
161 style: *style,
162 })]
163 })
164 );
165 }
166 }
167
168 #[test]
test_integer_with_minus()169 fn test_integer_with_minus() {
170 for (format_char, primitive, style) in INTEGERS {
171 assert_eq!(
172 FormatString::parse_printf(&format!("%-5{format_char}")),
173 Ok(FormatString {
174 fragments: vec![FormatFragment::Conversion(ConversionSpec {
175 argument: Argument::None,
176 fill: ' ',
177 alignment: Alignment::Left,
178 flags: [Flag::LeftJustify].into_iter().collect(),
179 min_field_width: MinFieldWidth::Fixed(5),
180 precision: Precision::None,
181 length: None,
182 primitive: *primitive,
183 style: *style,
184 })]
185 })
186 );
187 }
188 }
189
190 #[test]
test_integer_with_plus()191 fn test_integer_with_plus() {
192 for (format_char, primitive, style) in INTEGERS {
193 assert_eq!(
194 FormatString::parse_printf(&format!("%+{format_char}")),
195 Ok(FormatString {
196 fragments: vec![FormatFragment::Conversion(ConversionSpec {
197 argument: Argument::None,
198 fill: ' ',
199 alignment: Alignment::None,
200 flags: [Flag::ForceSign].into_iter().collect(),
201 min_field_width: MinFieldWidth::None,
202 precision: Precision::None,
203 length: None,
204 primitive: *primitive,
205 style: *style,
206 })]
207 })
208 );
209 }
210 }
211
212 #[test]
test_integer_with_blank_space()213 fn test_integer_with_blank_space() {
214 for (format_char, primitive, style) in INTEGERS {
215 assert_eq!(
216 FormatString::parse_printf(&format!("% {format_char}")),
217 Ok(FormatString {
218 fragments: vec![FormatFragment::Conversion(ConversionSpec {
219 argument: Argument::None,
220 fill: ' ',
221 alignment: Alignment::None,
222 flags: [Flag::SpaceSign].into_iter().collect(),
223 min_field_width: MinFieldWidth::None,
224 precision: Precision::None,
225 length: None,
226 primitive: *primitive,
227 style: *style,
228 })]
229 })
230 );
231 }
232 }
233
234 #[test]
test_integer_with_plus_and_blank_space_ignores_blank_space()235 fn test_integer_with_plus_and_blank_space_ignores_blank_space() {
236 for (format_char, primitive, style) in INTEGERS {
237 assert_eq!(
238 FormatString::parse_printf(&format!("%+ {format_char}")),
239 Ok(FormatString {
240 fragments: vec![FormatFragment::Conversion(ConversionSpec {
241 argument: Argument::None,
242 fill: ' ',
243 alignment: Alignment::None,
244 flags: [Flag::ForceSign, Flag::SpaceSign].into_iter().collect(),
245 min_field_width: MinFieldWidth::None,
246 precision: Precision::None,
247 length: None,
248 primitive: *primitive,
249 style: *style,
250 })]
251 })
252 );
253
254 assert_eq!(
255 FormatString::parse_printf(&format!("% +{format_char}")),
256 Ok(FormatString {
257 fragments: vec![FormatFragment::Conversion(ConversionSpec {
258 argument: Argument::None,
259 fill: ' ',
260 alignment: Alignment::None,
261 flags: [Flag::ForceSign, Flag::SpaceSign].into_iter().collect(),
262 min_field_width: MinFieldWidth::None,
263 precision: Precision::None,
264 length: None,
265 primitive: *primitive,
266 style: *style,
267 })]
268 })
269 );
270 }
271 }
272
273 #[test]
test_integer_with_hash()274 fn test_integer_with_hash() {
275 for (format_char, primitive, style) in INTEGERS {
276 assert_eq!(
277 FormatString::parse_printf(&format!("%#{format_char}")),
278 Ok(FormatString {
279 fragments: vec![FormatFragment::Conversion(ConversionSpec {
280 argument: Argument::None,
281 fill: ' ',
282 alignment: Alignment::None,
283 flags: [Flag::AlternateSyntax].into_iter().collect(),
284 min_field_width: MinFieldWidth::None,
285 precision: Precision::None,
286 length: None,
287 primitive: *primitive,
288 style: *style,
289 })]
290 })
291 );
292 }
293 }
294
295 #[test]
test_integer_with_zero()296 fn test_integer_with_zero() {
297 for (format_char, primitive, style) in INTEGERS {
298 assert_eq!(
299 FormatString::parse_printf(&format!("%0{format_char}")),
300 Ok(FormatString {
301 fragments: vec![FormatFragment::Conversion(ConversionSpec {
302 argument: Argument::None,
303 fill: ' ',
304 alignment: Alignment::None,
305 flags: [Flag::LeadingZeros].into_iter().collect(),
306 min_field_width: MinFieldWidth::None,
307 precision: Precision::None,
308 length: None,
309 primitive: *primitive,
310 style: *style,
311 })]
312 })
313 );
314 }
315 }
316
317 #[test]
test_integer_with_length()318 fn test_integer_with_length() {
319 for (format_char, primitive, style) in INTEGERS {
320 assert_eq!(
321 FormatString::parse_printf(&format!("%hh{format_char}")),
322 Ok(FormatString {
323 fragments: vec![FormatFragment::Conversion(ConversionSpec {
324 argument: Argument::None,
325 fill: ' ',
326 alignment: Alignment::None,
327 flags: HashSet::new(),
328 min_field_width: MinFieldWidth::None,
329 precision: Precision::None,
330 length: Some(Length::Char),
331 primitive: *primitive,
332 style: *style,
333 })]
334 })
335 );
336
337 assert_eq!(
338 FormatString::parse_printf(&format!("%h{format_char}")),
339 Ok(FormatString {
340 fragments: vec![FormatFragment::Conversion(ConversionSpec {
341 argument: Argument::None,
342 fill: ' ',
343 alignment: Alignment::None,
344 flags: HashSet::new(),
345 min_field_width: MinFieldWidth::None,
346 precision: Precision::None,
347 length: Some(Length::Short),
348 primitive: *primitive,
349 style: *style,
350 })]
351 })
352 );
353
354 assert_eq!(
355 FormatString::parse_printf(&format!("%l{format_char}")),
356 Ok(FormatString {
357 fragments: vec![FormatFragment::Conversion(ConversionSpec {
358 argument: Argument::None,
359 fill: ' ',
360 alignment: Alignment::None,
361 flags: HashSet::new(),
362 min_field_width: MinFieldWidth::None,
363 precision: Precision::None,
364 length: Some(Length::Long),
365 primitive: *primitive,
366 style: *style,
367 })]
368 })
369 );
370
371 assert_eq!(
372 FormatString::parse_printf(&format!("%ll{format_char}")),
373 Ok(FormatString {
374 fragments: vec![FormatFragment::Conversion(ConversionSpec {
375 argument: Argument::None,
376 fill: ' ',
377 alignment: Alignment::None,
378 flags: HashSet::new(),
379 min_field_width: MinFieldWidth::None,
380 precision: Precision::None,
381 length: Some(Length::LongLong),
382 primitive: *primitive,
383 style: *style,
384 })]
385 })
386 );
387
388 assert_eq!(
389 FormatString::parse_printf(&format!("%j{format_char}")),
390 Ok(FormatString {
391 fragments: vec![FormatFragment::Conversion(ConversionSpec {
392 argument: Argument::None,
393 fill: ' ',
394 alignment: Alignment::None,
395 flags: HashSet::new(),
396 min_field_width: MinFieldWidth::None,
397 precision: Precision::None,
398 length: Some(Length::IntMax),
399 primitive: *primitive,
400 style: *style,
401 })]
402 })
403 );
404
405 assert_eq!(
406 FormatString::parse_printf(&format!("%z{format_char}")),
407 Ok(FormatString {
408 fragments: vec![FormatFragment::Conversion(ConversionSpec {
409 argument: Argument::None,
410 fill: ' ',
411 alignment: Alignment::None,
412 flags: HashSet::new(),
413 min_field_width: MinFieldWidth::None,
414 precision: Precision::None,
415 length: Some(Length::Size),
416 primitive: *primitive,
417 style: *style,
418 })]
419 })
420 );
421
422 assert_eq!(
423 FormatString::parse_printf(&format!("%t{format_char}")),
424 Ok(FormatString {
425 fragments: vec![FormatFragment::Conversion(ConversionSpec {
426 argument: Argument::None,
427 fill: ' ',
428 alignment: Alignment::None,
429 flags: HashSet::new(),
430 min_field_width: MinFieldWidth::None,
431 precision: Precision::None,
432 length: Some(Length::PointerDiff),
433 primitive: *primitive,
434 style: *style,
435 })]
436 })
437 );
438 }
439 }
440
441 const FLOATS: &[(&str, Primitive, Style)] = &[
442 ("f", Primitive::Float, Style::None),
443 ("e", Primitive::Float, Style::Exponential),
444 ("E", Primitive::Float, Style::UpperExponential),
445 ];
446
447 #[test]
test_float()448 fn test_float() {
449 for (format_char, primitive, style) in FLOATS {
450 assert_eq!(
451 FormatString::parse_printf(&format!("%{format_char}")),
452 Ok(FormatString {
453 fragments: vec![FormatFragment::Conversion(ConversionSpec {
454 argument: Argument::None,
455 fill: ' ',
456 alignment: Alignment::None,
457 flags: HashSet::new(),
458 min_field_width: MinFieldWidth::None,
459 precision: Precision::None,
460 length: None,
461 primitive: *primitive,
462 style: *style,
463 })]
464 })
465 );
466 }
467 }
468
469 #[test]
test_float_with_minus()470 fn test_float_with_minus() {
471 for (format_char, primitive, style) in FLOATS {
472 assert_eq!(
473 FormatString::parse_printf(&format!("%-10{format_char}")),
474 Ok(FormatString {
475 fragments: vec![FormatFragment::Conversion(ConversionSpec {
476 argument: Argument::None,
477 fill: ' ',
478 alignment: Alignment::Left,
479 flags: [Flag::LeftJustify].into_iter().collect(),
480 min_field_width: MinFieldWidth::Fixed(10),
481 precision: Precision::None,
482 length: None,
483 primitive: *primitive,
484 style: *style,
485 })]
486 })
487 );
488 }
489 }
490
491 #[test]
test_float_with_plus()492 fn test_float_with_plus() {
493 for (format_char, primitive, style) in FLOATS {
494 assert_eq!(
495 FormatString::parse_printf(&format!("%+{format_char}")),
496 Ok(FormatString {
497 fragments: vec![FormatFragment::Conversion(ConversionSpec {
498 argument: Argument::None,
499 fill: ' ',
500 alignment: Alignment::None,
501 flags: [Flag::ForceSign].into_iter().collect(),
502 min_field_width: MinFieldWidth::None,
503 precision: Precision::None,
504 length: None,
505 primitive: *primitive,
506 style: *style,
507 })]
508 })
509 );
510 }
511 }
512
513 #[test]
test_float_with_blank_space()514 fn test_float_with_blank_space() {
515 for (format_char, primitive, style) in FLOATS {
516 assert_eq!(
517 FormatString::parse_printf(&format!("% {format_char}")),
518 Ok(FormatString {
519 fragments: vec![FormatFragment::Conversion(ConversionSpec {
520 argument: Argument::None,
521 fill: ' ',
522 alignment: Alignment::None,
523 flags: [Flag::SpaceSign].into_iter().collect(),
524 min_field_width: MinFieldWidth::None,
525 precision: Precision::None,
526 length: None,
527 primitive: *primitive,
528 style: *style,
529 })]
530 })
531 );
532 }
533 }
534
535 #[test]
test_float_with_plus_and_blank_space_ignores_blank_space()536 fn test_float_with_plus_and_blank_space_ignores_blank_space() {
537 for (format_char, primitive, style) in FLOATS {
538 assert_eq!(
539 FormatString::parse_printf(&format!("%+ {format_char}")),
540 Ok(FormatString {
541 fragments: vec![FormatFragment::Conversion(ConversionSpec {
542 argument: Argument::None,
543 fill: ' ',
544 alignment: Alignment::None,
545 flags: [Flag::ForceSign, Flag::SpaceSign].into_iter().collect(),
546 min_field_width: MinFieldWidth::None,
547 precision: Precision::None,
548 length: None,
549 primitive: *primitive,
550 style: *style,
551 })]
552 })
553 );
554
555 assert_eq!(
556 FormatString::parse_printf(&format!("% +{format_char}")),
557 Ok(FormatString {
558 fragments: vec![FormatFragment::Conversion(ConversionSpec {
559 argument: Argument::None,
560 fill: ' ',
561 alignment: Alignment::None,
562 flags: [Flag::ForceSign, Flag::SpaceSign].into_iter().collect(),
563 min_field_width: MinFieldWidth::None,
564 precision: Precision::None,
565 length: None,
566 primitive: *primitive,
567 style: *style,
568 })]
569 })
570 );
571 }
572 }
573
574 #[test]
test_float_with_hash()575 fn test_float_with_hash() {
576 for (format_char, primitive, style) in FLOATS {
577 assert_eq!(
578 FormatString::parse_printf(&format!("%.0{format_char}")),
579 Ok(FormatString {
580 fragments: vec![FormatFragment::Conversion(ConversionSpec {
581 argument: Argument::None,
582 fill: ' ',
583 alignment: Alignment::None,
584 flags: [].into_iter().collect(),
585 min_field_width: MinFieldWidth::None,
586 precision: Precision::Fixed(0),
587 length: None,
588 primitive: *primitive,
589 style: *style,
590 })]
591 })
592 );
593
594 assert_eq!(
595 FormatString::parse_printf(&format!("%#.0{format_char}")),
596 Ok(FormatString {
597 fragments: vec![FormatFragment::Conversion(ConversionSpec {
598 argument: Argument::None,
599 fill: ' ',
600 alignment: Alignment::None,
601 flags: [Flag::AlternateSyntax].into_iter().collect(),
602 min_field_width: MinFieldWidth::None,
603 precision: Precision::Fixed(0),
604 length: None,
605 primitive: *primitive,
606 style: *style,
607 })]
608 })
609 );
610 }
611 }
612
613 #[test]
test_float_with_zero()614 fn test_float_with_zero() {
615 for (format_char, primitive, style) in FLOATS {
616 assert_eq!(
617 FormatString::parse_printf(&format!("%010{format_char}")),
618 Ok(FormatString {
619 fragments: vec![FormatFragment::Conversion(ConversionSpec {
620 argument: Argument::None,
621 fill: ' ',
622 alignment: Alignment::None,
623 flags: [Flag::LeadingZeros].into_iter().collect(),
624 min_field_width: MinFieldWidth::Fixed(10),
625 precision: Precision::None,
626 length: None,
627 primitive: *primitive,
628 style: *style,
629 })]
630 })
631 );
632 }
633 }
634
635 #[test]
test_float_with_length()636 fn test_float_with_length() {
637 for (format_char, primitive, style) in FLOATS {
638 assert_eq!(
639 FormatString::parse_printf(&format!("%hh{format_char}")),
640 Ok(FormatString {
641 fragments: vec![FormatFragment::Conversion(ConversionSpec {
642 argument: Argument::None,
643 fill: ' ',
644 alignment: Alignment::None,
645 flags: HashSet::new(),
646 min_field_width: MinFieldWidth::None,
647 precision: Precision::None,
648 length: Some(Length::Char),
649 primitive: *primitive,
650 style: *style,
651 })]
652 })
653 );
654
655 assert_eq!(
656 FormatString::parse_printf(&format!("%h{format_char}")),
657 Ok(FormatString {
658 fragments: vec![FormatFragment::Conversion(ConversionSpec {
659 argument: Argument::None,
660 fill: ' ',
661 alignment: Alignment::None,
662 flags: HashSet::new(),
663 min_field_width: MinFieldWidth::None,
664 precision: Precision::None,
665 length: Some(Length::Short),
666 primitive: *primitive,
667 style: *style,
668 })]
669 })
670 );
671
672 assert_eq!(
673 FormatString::parse_printf(&format!("%l{format_char}")),
674 Ok(FormatString {
675 fragments: vec![FormatFragment::Conversion(ConversionSpec {
676 argument: Argument::None,
677 fill: ' ',
678 alignment: Alignment::None,
679 flags: HashSet::new(),
680 min_field_width: MinFieldWidth::None,
681 precision: Precision::None,
682 length: Some(Length::Long),
683 primitive: *primitive,
684 style: *style,
685 })]
686 })
687 );
688
689 assert_eq!(
690 FormatString::parse_printf(&format!("%ll{format_char}")),
691 Ok(FormatString {
692 fragments: vec![FormatFragment::Conversion(ConversionSpec {
693 argument: Argument::None,
694 fill: ' ',
695 alignment: Alignment::None,
696 flags: HashSet::new(),
697 min_field_width: MinFieldWidth::None,
698 precision: Precision::None,
699 length: Some(Length::LongLong),
700 primitive: *primitive,
701 style: *style,
702 })]
703 })
704 );
705
706 assert_eq!(
707 FormatString::parse_printf(&format!("%j{format_char}")),
708 Ok(FormatString {
709 fragments: vec![FormatFragment::Conversion(ConversionSpec {
710 argument: Argument::None,
711 fill: ' ',
712 alignment: Alignment::None,
713 flags: HashSet::new(),
714 min_field_width: MinFieldWidth::None,
715 precision: Precision::None,
716 length: Some(Length::IntMax),
717 primitive: *primitive,
718 style: *style,
719 })]
720 })
721 );
722
723 assert_eq!(
724 FormatString::parse_printf(&format!("%z{format_char}")),
725 Ok(FormatString {
726 fragments: vec![FormatFragment::Conversion(ConversionSpec {
727 argument: Argument::None,
728 fill: ' ',
729 alignment: Alignment::None,
730 flags: HashSet::new(),
731 min_field_width: MinFieldWidth::None,
732 precision: Precision::None,
733 length: Some(Length::Size),
734 primitive: *primitive,
735 style: *style,
736 })]
737 })
738 );
739
740 assert_eq!(
741 FormatString::parse_printf(&format!("%t{format_char}")),
742 Ok(FormatString {
743 fragments: vec![FormatFragment::Conversion(ConversionSpec {
744 argument: Argument::None,
745 fill: ' ',
746 alignment: Alignment::None,
747 flags: HashSet::new(),
748 min_field_width: MinFieldWidth::None,
749 precision: Precision::None,
750 length: Some(Length::PointerDiff),
751 primitive: *primitive,
752 style: *style,
753 })]
754 })
755 );
756
757 assert_eq!(
758 FormatString::parse_printf(&format!("%L{format_char}")),
759 Ok(FormatString {
760 fragments: vec![FormatFragment::Conversion(ConversionSpec {
761 argument: Argument::None,
762 fill: ' ',
763 alignment: Alignment::None,
764 flags: HashSet::new(),
765 min_field_width: MinFieldWidth::None,
766 precision: Precision::None,
767 length: Some(Length::LongDouble),
768 primitive: *primitive,
769 style: *style,
770 })]
771 })
772 );
773 }
774 }
775
776 #[test]
test_float_with_width()777 fn test_float_with_width() {
778 for (format_char, primitive, style) in FLOATS {
779 assert_eq!(
780 FormatString::parse_printf(&format!("%9{format_char}")),
781 Ok(FormatString {
782 fragments: vec![FormatFragment::Conversion(ConversionSpec {
783 argument: Argument::None,
784 fill: ' ',
785 alignment: Alignment::None,
786 flags: [].into_iter().collect(),
787 min_field_width: MinFieldWidth::Fixed(9),
788 precision: Precision::None,
789 length: None,
790 primitive: *primitive,
791 style: *style,
792 })]
793 })
794 );
795 }
796 }
797
798 #[test]
test_float_with_multidigit_width()799 fn test_float_with_multidigit_width() {
800 for (format_char, primitive, style) in FLOATS {
801 assert_eq!(
802 FormatString::parse_printf(&format!("%10{format_char}")),
803 Ok(FormatString {
804 fragments: vec![FormatFragment::Conversion(ConversionSpec {
805 argument: Argument::None,
806 fill: ' ',
807 alignment: Alignment::None,
808 flags: [].into_iter().collect(),
809 min_field_width: MinFieldWidth::Fixed(10),
810 precision: Precision::None,
811 length: None,
812 primitive: *primitive,
813 style: *style,
814 })]
815 })
816 );
817 }
818 }
819
820 #[test]
test_float_with_star_width()821 fn test_float_with_star_width() {
822 for (format_char, primitive, style) in FLOATS {
823 assert_eq!(
824 FormatString::parse_printf(&format!("%*{format_char}")),
825 Ok(FormatString {
826 fragments: vec![FormatFragment::Conversion(ConversionSpec {
827 argument: Argument::None,
828 fill: ' ',
829 alignment: Alignment::None,
830 flags: [].into_iter().collect(),
831 min_field_width: MinFieldWidth::Variable,
832 precision: Precision::None,
833 length: None,
834 primitive: *primitive,
835 style: *style,
836 })]
837 })
838 );
839 }
840 }
841
842 #[test]
test_float_with_precision()843 fn test_float_with_precision() {
844 for (format_char, primitive, style) in FLOATS {
845 assert_eq!(
846 FormatString::parse_printf(&format!("%.4{format_char}")),
847 Ok(FormatString {
848 fragments: vec![FormatFragment::Conversion(ConversionSpec {
849 argument: Argument::None,
850 fill: ' ',
851 alignment: Alignment::None,
852 flags: [].into_iter().collect(),
853 min_field_width: MinFieldWidth::None,
854 precision: Precision::Fixed(4),
855 length: None,
856 primitive: *primitive,
857 style: *style,
858 })]
859 })
860 );
861 }
862 }
863
864 #[test]
test_float_with_multidigit_precision()865 fn test_float_with_multidigit_precision() {
866 for (format_char, primitive, style) in FLOATS {
867 assert_eq!(
868 FormatString::parse_printf(&format!("%.10{format_char}")),
869 Ok(FormatString {
870 fragments: vec![FormatFragment::Conversion(ConversionSpec {
871 argument: Argument::None,
872 fill: ' ',
873 alignment: Alignment::None,
874 flags: [].into_iter().collect(),
875 min_field_width: MinFieldWidth::None,
876 precision: Precision::Fixed(10),
877 length: None,
878 primitive: *primitive,
879 style: *style,
880 })]
881 })
882 );
883 }
884 }
885
886 #[test]
test_float_with_star_precision()887 fn test_float_with_star_precision() {
888 for (format_char, primitive, style) in FLOATS {
889 assert_eq!(
890 FormatString::parse_printf(&format!("%.*{format_char}")),
891 Ok(FormatString {
892 fragments: vec![FormatFragment::Conversion(ConversionSpec {
893 argument: Argument::None,
894 fill: ' ',
895 alignment: Alignment::None,
896 flags: [].into_iter().collect(),
897 min_field_width: MinFieldWidth::None,
898 precision: Precision::Variable,
899 length: None,
900 primitive: *primitive,
901 style: *style,
902 })]
903 })
904 );
905 }
906 }
907
908 #[test]
test_float_with_star_width_and_star_precision()909 fn test_float_with_star_width_and_star_precision() {
910 for (format_char, primitive, style) in FLOATS {
911 assert_eq!(
912 FormatString::parse_printf(&format!("%*.*{format_char}")),
913 Ok(FormatString {
914 fragments: vec![FormatFragment::Conversion(ConversionSpec {
915 argument: Argument::None,
916 fill: ' ',
917 alignment: Alignment::None,
918 flags: [].into_iter().collect(),
919 min_field_width: MinFieldWidth::Variable,
920 precision: Precision::Variable,
921 length: None,
922 primitive: *primitive,
923 style: *style,
924 })]
925 })
926 );
927 }
928 }
929
930 #[test]
test_char()931 fn test_char() {
932 assert_eq!(
933 FormatString::parse_printf("%c"),
934 Ok(FormatString {
935 fragments: vec![FormatFragment::Conversion(ConversionSpec {
936 argument: Argument::None,
937 fill: ' ',
938 alignment: Alignment::None,
939 flags: [].into_iter().collect(),
940 min_field_width: MinFieldWidth::None,
941 precision: Precision::None,
942 length: None,
943 primitive: Primitive::Character,
944 style: Style::None,
945 })]
946 })
947 );
948 }
949
950 #[test]
test_char_with_minus()951 fn test_char_with_minus() {
952 assert_eq!(
953 FormatString::parse_printf("%-5c"),
954 Ok(FormatString {
955 fragments: vec![FormatFragment::Conversion(ConversionSpec {
956 argument: Argument::None,
957 fill: ' ',
958 alignment: Alignment::Left,
959 flags: [Flag::LeftJustify].into_iter().collect(),
960 min_field_width: MinFieldWidth::Fixed(5),
961 precision: Precision::None,
962 length: None,
963 primitive: Primitive::Character,
964 style: Style::None,
965 })]
966 })
967 );
968 }
969
970 #[test]
test_char_with_plus()971 fn test_char_with_plus() {
972 // TODO: b/281750433 - This test should fail.
973 assert!(FormatString::parse_printf("%+c").is_ok());
974 }
975
976 #[test]
test_char_with_blank_space()977 fn test_char_with_blank_space() {
978 // TODO: b/281750433 - This test should fail.
979 assert!(FormatString::parse_printf("% c").is_ok());
980 }
981
982 #[test]
test_char_with_hash()983 fn test_char_with_hash() {
984 // TODO: b/281750433 - This test should fail.
985 assert!(FormatString::parse_printf("%#c").is_ok());
986 }
987
988 #[test]
test_char_with_zero()989 fn test_char_with_zero() {
990 // TODO: b/281750433 - This test should fail.
991 assert!(FormatString::parse_printf("%0c").is_ok());
992 }
993
994 #[test]
test_char_with_length()995 fn test_char_with_length() {
996 // Length modifiers are ignored by %c but are still returned by the
997 // parser.
998 assert_eq!(
999 FormatString::parse_printf("%hhc"),
1000 Ok(FormatString {
1001 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1002 argument: Argument::None,
1003 fill: ' ',
1004 alignment: Alignment::None,
1005 flags: HashSet::new(),
1006 min_field_width: MinFieldWidth::None,
1007 precision: Precision::None,
1008 length: Some(Length::Char),
1009 primitive: Primitive::Character,
1010 style: Style::None,
1011 })]
1012 })
1013 );
1014
1015 assert_eq!(
1016 FormatString::parse_printf("%hc"),
1017 Ok(FormatString {
1018 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1019 argument: Argument::None,
1020 fill: ' ',
1021 alignment: Alignment::None,
1022 flags: HashSet::new(),
1023 min_field_width: MinFieldWidth::None,
1024 precision: Precision::None,
1025 length: Some(Length::Short),
1026 primitive: Primitive::Character,
1027 style: Style::None,
1028 })]
1029 })
1030 );
1031
1032 assert_eq!(
1033 FormatString::parse_printf("%lc"),
1034 Ok(FormatString {
1035 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1036 argument: Argument::None,
1037 fill: ' ',
1038 alignment: Alignment::None,
1039 flags: HashSet::new(),
1040 min_field_width: MinFieldWidth::None,
1041 precision: Precision::None,
1042 length: Some(Length::Long),
1043 primitive: Primitive::Character,
1044 style: Style::None,
1045 })]
1046 })
1047 );
1048
1049 assert_eq!(
1050 FormatString::parse_printf("%llc"),
1051 Ok(FormatString {
1052 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1053 argument: Argument::None,
1054 fill: ' ',
1055 alignment: Alignment::None,
1056 flags: HashSet::new(),
1057 min_field_width: MinFieldWidth::None,
1058 precision: Precision::None,
1059 length: Some(Length::LongLong),
1060 primitive: Primitive::Character,
1061 style: Style::None,
1062 })]
1063 })
1064 );
1065
1066 assert_eq!(
1067 FormatString::parse_printf("%jc"),
1068 Ok(FormatString {
1069 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1070 argument: Argument::None,
1071 fill: ' ',
1072 alignment: Alignment::None,
1073 flags: HashSet::new(),
1074 min_field_width: MinFieldWidth::None,
1075 precision: Precision::None,
1076 length: Some(Length::IntMax),
1077 primitive: Primitive::Character,
1078 style: Style::None,
1079 })]
1080 })
1081 );
1082
1083 assert_eq!(
1084 FormatString::parse_printf("%zc"),
1085 Ok(FormatString {
1086 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1087 argument: Argument::None,
1088 fill: ' ',
1089 alignment: Alignment::None,
1090 flags: HashSet::new(),
1091 min_field_width: MinFieldWidth::None,
1092 precision: Precision::None,
1093 length: Some(Length::Size),
1094 primitive: Primitive::Character,
1095 style: Style::None,
1096 })]
1097 })
1098 );
1099
1100 assert_eq!(
1101 FormatString::parse_printf("%tc"),
1102 Ok(FormatString {
1103 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1104 argument: Argument::None,
1105 fill: ' ',
1106 alignment: Alignment::None,
1107 flags: HashSet::new(),
1108 min_field_width: MinFieldWidth::None,
1109 precision: Precision::None,
1110 length: Some(Length::PointerDiff),
1111 primitive: Primitive::Character,
1112 style: Style::None,
1113 })]
1114 })
1115 );
1116
1117 assert_eq!(
1118 FormatString::parse_printf("%Lc"),
1119 Ok(FormatString {
1120 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1121 argument: Argument::None,
1122 fill: ' ',
1123 alignment: Alignment::None,
1124 flags: HashSet::new(),
1125 min_field_width: MinFieldWidth::None,
1126 precision: Precision::None,
1127 length: Some(Length::LongDouble),
1128 primitive: Primitive::Character,
1129 style: Style::None,
1130 })]
1131 })
1132 );
1133 }
1134
1135 #[test]
test_char_with_width()1136 fn test_char_with_width() {
1137 assert_eq!(
1138 FormatString::parse_printf("%5c"),
1139 Ok(FormatString {
1140 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1141 argument: Argument::None,
1142 fill: ' ',
1143 alignment: Alignment::None,
1144 flags: [].into_iter().collect(),
1145 min_field_width: MinFieldWidth::Fixed(5),
1146 precision: Precision::None,
1147 length: None,
1148 primitive: Primitive::Character,
1149 style: Style::None,
1150 })]
1151 })
1152 );
1153 }
1154
1155 #[test]
test_char_with_multidigit_width()1156 fn test_char_with_multidigit_width() {
1157 assert_eq!(
1158 FormatString::parse_printf("%10c"),
1159 Ok(FormatString {
1160 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1161 argument: Argument::None,
1162 fill: ' ',
1163 alignment: Alignment::None,
1164 flags: [].into_iter().collect(),
1165 min_field_width: MinFieldWidth::Fixed(10),
1166 precision: Precision::None,
1167 length: None,
1168 primitive: Primitive::Character,
1169 style: Style::None,
1170 })]
1171 })
1172 );
1173 }
1174
1175 #[test]
test_char_with_star_width()1176 fn test_char_with_star_width() {
1177 assert_eq!(
1178 FormatString::parse_printf("%*c"),
1179 Ok(FormatString {
1180 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1181 argument: Argument::None,
1182 fill: ' ',
1183 alignment: Alignment::None,
1184 flags: [].into_iter().collect(),
1185 min_field_width: MinFieldWidth::Variable,
1186 precision: Precision::None,
1187 length: None,
1188 primitive: Primitive::Character,
1189 style: Style::None,
1190 })]
1191 })
1192 );
1193 }
1194
1195 #[test]
test_char_with_precision()1196 fn test_char_with_precision() {
1197 // TODO: b/281750433 - This test should fail.
1198 assert!(FormatString::parse_printf("%.4c").is_ok());
1199 }
1200
1201 #[test]
test_long_char_with_hash()1202 fn test_long_char_with_hash() {
1203 // TODO: b/281750433 - This test should fail.
1204 assert!(FormatString::parse_printf("%#lc").is_ok());
1205 }
1206
1207 #[test]
test_long_char_with_zero()1208 fn test_long_char_with_zero() {
1209 // TODO: b/281750433 - This test should fail.
1210 assert!(FormatString::parse_printf("%0lc").is_ok());
1211 }
1212
1213 #[test]
test_string()1214 fn test_string() {
1215 assert_eq!(
1216 FormatString::parse_printf("%s"),
1217 Ok(FormatString {
1218 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1219 argument: Argument::None,
1220 fill: ' ',
1221 alignment: Alignment::None,
1222 flags: [].into_iter().collect(),
1223 min_field_width: MinFieldWidth::None,
1224 precision: Precision::None,
1225 length: None,
1226 primitive: Primitive::String,
1227 style: Style::None,
1228 })]
1229 })
1230 );
1231 }
1232
1233 #[test]
test_string_with_minus()1234 fn test_string_with_minus() {
1235 assert_eq!(
1236 FormatString::parse_printf("%-6s"),
1237 Ok(FormatString {
1238 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1239 argument: Argument::None,
1240 fill: ' ',
1241 alignment: Alignment::Left,
1242 flags: [Flag::LeftJustify].into_iter().collect(),
1243 min_field_width: MinFieldWidth::Fixed(6),
1244 precision: Precision::None,
1245 length: None,
1246 primitive: Primitive::String,
1247 style: Style::None,
1248 })]
1249 })
1250 );
1251 }
1252
1253 #[test]
test_string_with_plus()1254 fn test_string_with_plus() {
1255 // TODO: b/281750433 - This test should fail.
1256 assert!(FormatString::parse_printf("%+s").is_ok());
1257 }
1258
1259 #[test]
test_string_with_blank_space()1260 fn test_string_with_blank_space() {
1261 // TODO: b/281750433 - This test should fail.
1262 assert!(FormatString::parse_printf("% s").is_ok());
1263 }
1264
1265 #[test]
test_string_with_hash()1266 fn test_string_with_hash() {
1267 // TODO: b/281750433 - This test should fail.
1268 assert!(FormatString::parse_printf("%#s").is_ok());
1269 }
1270
1271 #[test]
test_string_with_zero()1272 fn test_string_with_zero() {
1273 // TODO: b/281750433 - This test should fail.
1274 assert!(FormatString::parse_printf("%0s").is_ok());
1275 }
1276
1277 #[test]
test_string_with_length()1278 fn test_string_with_length() {
1279 // Length modifiers are ignored by %s but are still returned by the
1280 // parser.
1281 assert_eq!(
1282 FormatString::parse_printf("%hhs"),
1283 Ok(FormatString {
1284 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1285 argument: Argument::None,
1286 fill: ' ',
1287 alignment: Alignment::None,
1288 flags: HashSet::new(),
1289 min_field_width: MinFieldWidth::None,
1290 precision: Precision::None,
1291 length: Some(Length::Char),
1292 primitive: Primitive::String,
1293 style: Style::None,
1294 })]
1295 })
1296 );
1297
1298 assert_eq!(
1299 FormatString::parse_printf("%hs"),
1300 Ok(FormatString {
1301 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1302 argument: Argument::None,
1303 fill: ' ',
1304 alignment: Alignment::None,
1305 flags: HashSet::new(),
1306 min_field_width: MinFieldWidth::None,
1307 precision: Precision::None,
1308 length: Some(Length::Short),
1309 primitive: Primitive::String,
1310 style: Style::None,
1311 })]
1312 })
1313 );
1314
1315 assert_eq!(
1316 FormatString::parse_printf("%ls"),
1317 Ok(FormatString {
1318 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1319 argument: Argument::None,
1320 fill: ' ',
1321 alignment: Alignment::None,
1322 flags: HashSet::new(),
1323 min_field_width: MinFieldWidth::None,
1324 precision: Precision::None,
1325 length: Some(Length::Long),
1326 primitive: Primitive::String,
1327 style: Style::None,
1328 })]
1329 })
1330 );
1331
1332 assert_eq!(
1333 FormatString::parse_printf("%lls"),
1334 Ok(FormatString {
1335 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1336 argument: Argument::None,
1337 fill: ' ',
1338 alignment: Alignment::None,
1339 flags: HashSet::new(),
1340 min_field_width: MinFieldWidth::None,
1341 precision: Precision::None,
1342 length: Some(Length::LongLong),
1343 primitive: Primitive::String,
1344 style: Style::None,
1345 })]
1346 })
1347 );
1348
1349 assert_eq!(
1350 FormatString::parse_printf("%js"),
1351 Ok(FormatString {
1352 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1353 argument: Argument::None,
1354 fill: ' ',
1355 alignment: Alignment::None,
1356 flags: HashSet::new(),
1357 min_field_width: MinFieldWidth::None,
1358 precision: Precision::None,
1359 length: Some(Length::IntMax),
1360 primitive: Primitive::String,
1361 style: Style::None,
1362 })]
1363 })
1364 );
1365
1366 assert_eq!(
1367 FormatString::parse_printf("%zs"),
1368 Ok(FormatString {
1369 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1370 argument: Argument::None,
1371 fill: ' ',
1372 alignment: Alignment::None,
1373 flags: HashSet::new(),
1374 min_field_width: MinFieldWidth::None,
1375 precision: Precision::None,
1376 length: Some(Length::Size),
1377 primitive: Primitive::String,
1378 style: Style::None,
1379 })]
1380 })
1381 );
1382
1383 assert_eq!(
1384 FormatString::parse_printf("%ts"),
1385 Ok(FormatString {
1386 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1387 argument: Argument::None,
1388 fill: ' ',
1389 alignment: Alignment::None,
1390 flags: HashSet::new(),
1391 min_field_width: MinFieldWidth::None,
1392 precision: Precision::None,
1393 length: Some(Length::PointerDiff),
1394 primitive: Primitive::String,
1395 style: Style::None,
1396 })]
1397 })
1398 );
1399
1400 assert_eq!(
1401 FormatString::parse_printf("%Ls"),
1402 Ok(FormatString {
1403 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1404 argument: Argument::None,
1405 fill: ' ',
1406 alignment: Alignment::None,
1407 flags: HashSet::new(),
1408 min_field_width: MinFieldWidth::None,
1409 precision: Precision::None,
1410 length: Some(Length::LongDouble),
1411 primitive: Primitive::String,
1412 style: Style::None,
1413 })]
1414 })
1415 );
1416 }
1417
1418 #[test]
test_string_with_width()1419 fn test_string_with_width() {
1420 assert_eq!(
1421 FormatString::parse_printf("%6s"),
1422 Ok(FormatString {
1423 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1424 argument: Argument::None,
1425 fill: ' ',
1426 alignment: Alignment::None,
1427 flags: [].into_iter().collect(),
1428 min_field_width: MinFieldWidth::Fixed(6),
1429 precision: Precision::None,
1430 length: None,
1431 primitive: Primitive::String,
1432 style: Style::None,
1433 })]
1434 })
1435 );
1436 }
1437
1438 #[test]
test_string_with_multidigit_width()1439 fn test_string_with_multidigit_width() {
1440 assert_eq!(
1441 FormatString::parse_printf("%10s"),
1442 Ok(FormatString {
1443 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1444 argument: Argument::None,
1445 fill: ' ',
1446 alignment: Alignment::None,
1447 flags: [].into_iter().collect(),
1448 min_field_width: MinFieldWidth::Fixed(10),
1449 precision: Precision::None,
1450 length: None,
1451 primitive: Primitive::String,
1452 style: Style::None,
1453 })]
1454 })
1455 );
1456 }
1457
1458 #[test]
test_string_with_star_width()1459 fn test_string_with_star_width() {
1460 assert_eq!(
1461 FormatString::parse_printf("%*s"),
1462 Ok(FormatString {
1463 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1464 argument: Argument::None,
1465 fill: ' ',
1466 alignment: Alignment::None,
1467 flags: [].into_iter().collect(),
1468 min_field_width: MinFieldWidth::Variable,
1469 precision: Precision::None,
1470 length: None,
1471 primitive: Primitive::String,
1472 style: Style::None,
1473 })]
1474 })
1475 );
1476 }
1477
1478 #[test]
test_string_with_star_precision()1479 fn test_string_with_star_precision() {
1480 assert_eq!(
1481 FormatString::parse_printf("%.3s"),
1482 Ok(FormatString {
1483 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1484 argument: Argument::None,
1485 fill: ' ',
1486 alignment: Alignment::None,
1487 flags: [].into_iter().collect(),
1488 min_field_width: MinFieldWidth::None,
1489 precision: Precision::Fixed(3),
1490 length: None,
1491 primitive: Primitive::String,
1492 style: Style::None,
1493 })]
1494 })
1495 );
1496 }
1497
1498 #[test]
test_string_with_multidigit_precision()1499 fn test_string_with_multidigit_precision() {
1500 assert_eq!(
1501 FormatString::parse_printf("%.10s"),
1502 Ok(FormatString {
1503 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1504 argument: Argument::None,
1505 fill: ' ',
1506 alignment: Alignment::None,
1507 flags: [].into_iter().collect(),
1508 min_field_width: MinFieldWidth::None,
1509 precision: Precision::Fixed(10),
1510 length: None,
1511 primitive: Primitive::String,
1512 style: Style::None,
1513 })]
1514 })
1515 );
1516 }
1517
1518 #[test]
test_string_with_width_and_precision()1519 fn test_string_with_width_and_precision() {
1520 assert_eq!(
1521 FormatString::parse_printf("%10.3s"),
1522 Ok(FormatString {
1523 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1524 argument: Argument::None,
1525 fill: ' ',
1526 alignment: Alignment::None,
1527 flags: [].into_iter().collect(),
1528 min_field_width: MinFieldWidth::Fixed(10),
1529 precision: Precision::Fixed(3),
1530 length: None,
1531 primitive: Primitive::String,
1532 style: Style::None,
1533 })]
1534 })
1535 );
1536 }
1537
1538 #[test]
test_string_with_star_width_and_star_precision()1539 fn test_string_with_star_width_and_star_precision() {
1540 assert_eq!(
1541 FormatString::parse_printf("%*.*s"),
1542 Ok(FormatString {
1543 fragments: vec![FormatFragment::Conversion(ConversionSpec {
1544 argument: Argument::None,
1545 fill: ' ',
1546 alignment: Alignment::None,
1547 flags: [].into_iter().collect(),
1548 min_field_width: MinFieldWidth::Variable,
1549 precision: Precision::Variable,
1550 length: None,
1551 primitive: Primitive::String,
1552 style: Style::None,
1553 })]
1554 })
1555 );
1556 }
1557
1558 #[test]
test_long_string_with_hash()1559 fn test_long_string_with_hash() {
1560 // TODO: b/281750433 - This test should fail.
1561 assert!(FormatString::parse_printf("%#ls").is_ok());
1562 }
1563
1564 #[test]
test_long_string_with_zero()1565 fn test_long_string_with_zero() {
1566 // TODO: b/281750433 - This test should fail.
1567 assert!(FormatString::parse_printf("%0ls").is_ok());
1568 }
1569