icu_datetime/provider/pattern/runtime/
display.rs
1use super::{
8 super::{GenericPatternItem, PatternItem},
9 GenericPattern, Pattern,
10};
11use crate::provider::fields::FieldSymbol;
12use alloc::string::String;
13use core::fmt::{self, Write};
14use writeable::{impl_display_with_writeable, Writeable};
15
16fn dump_buffer_into_formatter<W: Write + ?Sized>(literal: &str, formatter: &mut W) -> fmt::Result {
20 if literal.is_empty() {
21 return Ok(());
22 }
23 let mut needs_escaping = false;
25 for ch in literal.chars() {
26 if ch.is_ascii_alphabetic() || ch == '\'' {
27 needs_escaping = true;
28 break;
29 }
30 }
31
32 if needs_escaping {
33 let mut ch_iter = literal.trim_end().chars().peekable();
34
35 while let Some(ch) = ch_iter.peek() {
37 if ch.is_whitespace() {
38 formatter.write_char(*ch)?;
39 ch_iter.next();
40 } else {
41 break;
42 }
43 }
44
45 formatter.write_char('\'')?;
47 for ch in ch_iter {
48 if ch == '\'' {
49 formatter.write_char('\\')?;
51 }
52 formatter.write_char(ch)?;
53 }
54 formatter.write_char('\'')?;
55
56 for ch in literal.chars().rev() {
58 if ch.is_whitespace() {
59 formatter.write_char(ch)?;
60 } else {
61 break;
62 }
63 }
64 } else {
65 formatter.write_str(literal)?;
66 }
67 Ok(())
68}
69
70impl Writeable for Pattern<'_> {
73 fn write_to<W: Write + ?Sized>(&self, formatter: &mut W) -> fmt::Result {
74 let mut buffer = String::new();
75 for pattern_item in self.items.iter() {
76 match pattern_item {
77 PatternItem::Field(field) => {
78 dump_buffer_into_formatter(&buffer, formatter)?;
79 buffer.clear();
80 let ch: char = field.symbol.into();
81 for _ in 0..field.length.to_len() {
82 formatter.write_char(ch)?;
83 }
84 if let FieldSymbol::DecimalSecond(decimal_second) = field.symbol {
85 formatter.write_char('.')?;
86 for _ in 0..(decimal_second as u8) {
87 formatter.write_char('S')?;
88 }
89 }
90 }
91 PatternItem::Literal(ch) => {
92 buffer.push(ch);
93 }
94 }
95 }
96 dump_buffer_into_formatter(&buffer, formatter)?;
97 buffer.clear();
98 Ok(())
99 }
100}
101
102impl_display_with_writeable!(Pattern<'_>);
103
104impl Writeable for GenericPattern<'_> {
105 fn write_to<W: Write + ?Sized>(&self, formatter: &mut W) -> fmt::Result {
106 let mut buffer = alloc::string::String::new();
107 for pattern_item in self.items.iter() {
108 match pattern_item {
109 GenericPatternItem::Placeholder(idx) => {
110 dump_buffer_into_formatter(&buffer, formatter)?;
111 buffer.clear();
112 write!(formatter, "{{{idx}}}")?;
113 }
114 GenericPatternItem::Literal(ch) => {
115 buffer.push(ch);
116 }
117 }
118 }
119 dump_buffer_into_formatter(&buffer, formatter)?;
120 buffer.clear();
121 Ok(())
122 }
123}
124
125impl_display_with_writeable!(GenericPattern<'_>);