1818
1919import java .io .IOException ;
2020import java .io .Writer ;
21- import java .text .Format ;
22- import java .util .Date ;
21+ import java .util .HashMap ;
2322import java .util .List ;
2423import java .util .Map ;
2524import java .util .ResourceBundle ;
25+ import java .util .function .Function ;
2626
2727import static org .httprpc .kilo .util .Optionals .*;
2828
3232public class CSVEncoder extends Encoder <Iterable <?>> {
3333 private List <String > keys ;
3434
35- private Format numberFormat = null ;
36- private Format booleanFormat = null ;
37- private Format dateFormat = null ;
35+ private Map <Class <?>, Function <Object , String >> formatters = new HashMap <>();
3836
3937 private ResourceBundle resourceBundle = null ;
4038
@@ -55,63 +53,21 @@ public CSVEncoder(List<String> keys) {
5553 }
5654
5755 /**
58- * Returns the number format .
56+ * Associates a formatter with a type .
5957 *
60- * @return
61- * The number format, or {@code null} if a number format has not been set.
62- */
63- public Format getNumberFormat () {
64- return numberFormat ;
65- }
66-
67- /**
68- * Sets the number format.
69- *
70- * @param numberFormat
71- * The number format, or {@code null} for no number format.
72- */
73- public void setNumberFormat (Format numberFormat ) {
74- this .numberFormat = numberFormat ;
75- }
76-
77- /**
78- * Returns the boolean format.
58+ * @param type
59+ * The type to format.
7960 *
80- * @return
81- * The boolean format, or {@code null} if a boolean format has not been set.
82- */
83- public Format getBooleanFormat () {
84- return booleanFormat ;
85- }
86-
87- /**
88- * Sets the boolean format.
89- *
90- * @param booleanFormat
91- * The boolean format, or {@code null} for no boolean format.
61+ * @param formatter
62+ * The formatter to apply to instances of the given type.
9263 */
93- public void setBooleanFormat (Format booleanFormat ) {
94- this .booleanFormat = booleanFormat ;
95- }
96-
97- /**
98- * Returns the date format.
99- *
100- * @return
101- * The date format, or {@code null} if a date format has not been set.
102- */
103- public Format getDateFormat () {
104- return dateFormat ;
105- }
64+ @ SuppressWarnings ("unchecked" )
65+ public <T > void format (Class <T > type , Function <? super T , String > formatter ) {
66+ if (type == null || formatter == null ) {
67+ throw new IllegalArgumentException ();
68+ }
10669
107- /**
108- * Sets the date format.
109- *
110- * @param dateFormat
111- * The date format, or {@code null} for no date format.
112- */
113- public void setDateFormat (Format dateFormat ) {
114- this .dateFormat = dateFormat ;
70+ formatters .put (type , (Function <Object , String >)formatter );
11571 }
11672
11773 /**
@@ -189,11 +145,24 @@ private void encode(Iterable<?> rows, Writer writer) throws IOException {
189145 var value = map .get (key );
190146
191147 if (value != null ) {
148+ var type = value .getClass ();
149+
150+ while (type != null ) {
151+ var formatter = formatters .get (type );
152+
153+ if (formatter != null ) {
154+ value = formatter .apply (value );
155+
156+ break ;
157+ }
158+
159+ type = type .getSuperclass ();
160+ }
161+
192162 switch (value ) {
193163 case CharSequence text -> encode (text , writer );
194164 case Number number -> encode (number , writer );
195165 case Boolean flag -> encode (flag , writer );
196- case Date date -> encode (date , writer );
197166 default -> encode (value .toString (), writer );
198167 }
199168 }
@@ -222,26 +191,10 @@ private void encode(CharSequence text, Writer writer) throws IOException {
222191 }
223192
224193 private void encode (Number number , Writer writer ) throws IOException {
225- if (numberFormat != null ) {
226- encode (numberFormat .format (number ), writer );
227- } else {
228- writer .write (number .toString ());
229- }
194+ writer .write (number .toString ());
230195 }
231196
232197 private void encode (Boolean flag , Writer writer ) throws IOException {
233- if (booleanFormat != null ) {
234- encode (booleanFormat .format (flag ), writer );
235- } else {
236- writer .write (flag .toString ());
237- }
238- }
239-
240- private void encode (Date date , Writer writer ) throws IOException {
241- if (dateFormat != null ) {
242- encode (dateFormat .format (date ), writer );
243- } else {
244- writer .write (String .valueOf (date .getTime ()));
245- }
198+ writer .write (flag .toString ());
246199 }
247200}
0 commit comments