chinese_format/placeholders.rs
1/// Defines a new **placeholder** type.
2///
3/// Every *placeholder* wraps a [ChineseFormat](crate::ChineseFormat) instance and implements [ChineseFormat](crate::ChineseFormat) as follows:
4///
5/// * first, convert the wrapped [ChineseFormat](crate::ChineseFormat) instance to [Chinese](crate::Chinese)
6///
7/// * if the result is not [omissible](crate::Chinese::omissible), return it unchanged
8///
9/// * otherwise, return a [Chinese](crate::Chinese) that is still [omissible](crate::Chinese::omissible),
10/// but whose [logograms](crate::Chinese::logograms) are the obtained by calling `$replacement_logograms.to_string()`.
11///
12/// Anyway, the `omissible` property of any placeholder always reflects the [Chinese](crate::Chinese) produced by the wrapped [ChineseFormat](crate::ChineseFormat) instance.
13///
14/// Last but not least, every placeholder can be built via its `new()` constructor.
15///
16/// # Ready-made placeholders
17///
18/// ## [LingPlaceholder]
19///
20/// Uses `零` in lieu of [omissible](crate::Chinese::omissible) logograms:
21///
22/// ```
23/// use chinese_format::*;
24///
25/// let placeholder_with_non_omissible = LingPlaceholder::new(&"二九零四");
26///
27/// assert_eq!(placeholder_with_non_omissible.to_chinese(Variant::Simplified), Chinese {
28/// logograms: "二九零四".to_string(),
29/// omissible: false
30/// });
31///
32/// assert_eq!(placeholder_with_non_omissible.to_chinese(Variant::Traditional), "二九零四");
33///
34///
35/// let placeholder_with_omissible = LingPlaceholder::new(&"");
36///
37/// assert_eq!(placeholder_with_omissible.to_chinese(Variant::Simplified), Chinese {
38/// logograms: "零".to_string(),
39/// omissible: true
40/// });
41///
42/// assert_eq!(placeholder_with_omissible.to_chinese(Variant::Traditional), "零");
43/// ```
44///
45/// ## [EmptyPlaceholder]
46///
47/// Uses an *empty string* in lieu of [omissible](crate::Chinese::omissible) logograms:
48///
49/// ```
50/// use chinese_format::*;
51///
52/// let placeholder_with_non_omissible = EmptyPlaceholder::new(&"二九零四");
53///
54/// assert_eq!(placeholder_with_non_omissible.to_chinese(Variant::Simplified), Chinese {
55/// logograms: "二九零四".to_string(),
56/// omissible: false
57/// });
58///
59/// assert_eq!(placeholder_with_non_omissible.to_chinese(Variant::Traditional), "二九零四");
60///
61///
62/// let placeholder_with_omissible = EmptyPlaceholder::new(&"");
63///
64/// assert_eq!(placeholder_with_omissible.to_chinese(Variant::Simplified), Chinese {
65/// logograms: "".to_string(),
66/// omissible: true
67/// });
68///
69/// assert_eq!(placeholder_with_omissible.to_chinese(Variant::Traditional), "");
70/// ```
71#[macro_export]
72macro_rules! define_string_placeholder {
73 (
74 //The visibility of the type to create.
75 $type_visibility: vis,
76
77 //The name of the type to create.
78 $type: ident,
79
80 //String of logograms in lieu of wrapped omissible ones.
81 $replacement_logograms: expr,
82
83 //The RustDoc string for the type to create.
84 $doc_string: literal
85 ) => {
86 #[doc = $doc_string]
87 $type_visibility struct $type<'a>(&'a dyn $crate::ChineseFormat);
88
89 impl <'a> $type<'a> {
90 pub fn new<T: $crate::ChineseFormat>(value: &'a T) -> Self {
91 Self(value)
92 }
93 }
94
95 impl <'a> $crate::ChineseFormat for $type<'a>{
96 fn to_chinese(&self, variant: $crate::Variant) -> $crate::Chinese {
97 let wrapped_chinese = self.0.to_chinese(variant);
98
99 let result_logograms = if wrapped_chinese.omissible {
100 $replacement_logograms.to_string()
101 } else {
102 wrapped_chinese.logograms
103 };
104
105 $crate::Chinese {
106 logograms: result_logograms,
107 omissible: wrapped_chinese.omissible
108 }
109 }
110 }
111 };
112}
113
114define_string_placeholder!(
115 pub,
116 LingPlaceholder,
117 "零",
118 "[Placeholder](crate::define_string_placeholder) replacing an *omissible* value with `零`."
119);
120
121define_string_placeholder!(
122 pub,
123 EmptyPlaceholder,
124 "",
125 "[Placeholder](crate::define_string_placeholder) replacing an *omissible* value with an empty string."
126);