1 module hunt.time.format.CompositePrinterParser; 2 3 import hunt.time.format.DateTimeParseContext; 4 import hunt.time.format.DateTimePrinterParser; 5 import hunt.time.format.DateTimePrintContext; 6 import hunt.time.temporal.TemporalField; 7 import hunt.util.StringBuilder; 8 9 import hunt.collection.List; 10 11 //----------------------------------------------------------------------- 12 /** 13 * Composite printer and parser. 14 */ 15 static final class CompositePrinterParser : DateTimePrinterParser 16 { 17 private DateTimePrinterParser[] printerParsers; 18 private bool optional; 19 20 this(List!(DateTimePrinterParser) printerParsers, bool optional) 21 { 22 auto a = printerParsers.toArray()/* new DateTimePrinterParser[printerParsers.size()] */; 23 // foreach (l; printerParsers) 24 // { 25 // if(l is null) 26 // { 27 // version(HUNT_DEBUG) trace("is null"); 28 // } 29 // version(HUNT_DEBUG) trace("----> :",(cast(Object)(l)).toString); 30 // a ~= l; 31 // } 32 // foreach(p ; a) 33 // { 34 // if(p is null) 35 // { 36 // import hunt.logging; 37 // version(HUNT_DEBUG) trace("is null"); 38 // } 39 // } 40 this(a, optional); 41 } 42 43 this(DateTimePrinterParser[] printerParsers, bool optional) 44 { 45 this.printerParsers = printerParsers; 46 // foreach(p ; this.printerParsers) 47 // { 48 // if(p is null) 49 // { 50 // import hunt.logging; 51 // version(HUNT_DEBUG) trace("is null"); 52 // } 53 // } 54 this.optional = optional; 55 } 56 57 /** 58 * Returns a copy of this printer-parser with the optional flag changed. 59 * 60 * @param optional the optional flag to set _in the copy 61 * @return the new printer-parser, not null 62 */ 63 public CompositePrinterParser withOptional(bool optional) 64 { 65 if (optional == this.optional) 66 { 67 return this; 68 } 69 return new CompositePrinterParser(printerParsers, optional); 70 } 71 72 override public bool format(DateTimePrintContext context, StringBuilder buf) 73 { 74 int length = buf.length(); 75 if (optional) 76 { 77 context.startOptional(); 78 } 79 try 80 { 81 foreach (DateTimePrinterParser pp; printerParsers) 82 { 83 if (pp.format(context, buf) == false) 84 { 85 buf.setLength(length); // reset buffer 86 return true; 87 } 88 } 89 } 90 finally 91 { 92 if (optional) 93 { 94 context.endOptional(); 95 } 96 } 97 return true; 98 } 99 100 override public int parse(DateTimeParseContext context, string text, int position) 101 { 102 if (optional) 103 { 104 context.startOptional(); 105 int pos = position; 106 foreach (DateTimePrinterParser pp; printerParsers) 107 { 108 pos = pp.parse(context, text, pos); 109 if (pos < 0) 110 { 111 context.endOptional(false); 112 return position; // return original position 113 } 114 } 115 context.endOptional(true); 116 return pos; 117 } 118 else 119 { 120 foreach (DateTimePrinterParser pp; printerParsers) 121 { 122 position = pp.parse(context, text, position); 123 if (position < 0) 124 { 125 break; 126 } 127 } 128 return position; 129 } 130 } 131 132 override public string toString() 133 { 134 StringBuilder buf = new StringBuilder(); 135 if (printerParsers !is null) 136 { 137 buf.append(optional ? "[" : "("); 138 foreach (DateTimePrinterParser pp; printerParsers) 139 { 140 buf.append(pp.toString); 141 } 142 buf.append(optional ? "]" : ")"); 143 } 144 return buf.toString(); 145 } 146 }