icu_datetime/provider/pattern/runtime/
display.rs1use 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 field.write_to(formatter)?;
81 if let FieldSymbol::DecimalSecond(decimal_second) = field.symbol {
82 formatter.write_char('.')?;
83 for _ in 0..(decimal_second as u8) {
84 formatter.write_char('S')?;
85 }
86 }
87 }
88 PatternItem::Literal(ch) => {
89 buffer.push(ch);
90 }
91 }
92 }
93 dump_buffer_into_formatter(&buffer, formatter)?;
94 buffer.clear();
95 Ok(())
96 }
97}
98
99impl_display_with_writeable!(Pattern<'_>);
100
101impl Writeable for GenericPattern<'_> {
102 fn write_to<W: Write + ?Sized>(&self, formatter: &mut W) -> fmt::Result {
103 let mut buffer = alloc::string::String::new();
104 for pattern_item in self.items.iter() {
105 match pattern_item {
106 GenericPatternItem::Placeholder(idx) => {
107 dump_buffer_into_formatter(&buffer, formatter)?;
108 buffer.clear();
109 write!(formatter, "{{{idx}}}")?;
110 }
111 GenericPatternItem::Literal(ch) => {
112 buffer.push(ch);
113 }
114 }
115 }
116 dump_buffer_into_formatter(&buffer, formatter)?;
117 buffer.clear();
118 Ok(())
119 }
120}
121
122impl_display_with_writeable!(GenericPattern<'_>);