1 /**
2 License:
3 Boost Software License - Version 1.0 - August 17th, 2003
4 5 Permission is hereby granted, free of charge, to any person or organization
6 obtaining a copy of the software and accompanying documentation covered by
7 this license (the "Software") to use, reproduce, display, distribute,
8 execute, and transmit the Software, and to prepare derivative works of the
9 Software, and to permit third-parties to whom the Software is furnished to
10 do so, all subject to the following:
11 12 The copyright notices in the Software and this entire statement, including
13 the above license grant, this restriction and the following disclaimer,
14 must be included in all copies of the Software, in whole or in part, and
15 all derivative works of the Software, unless such copies or derivative
16 works are solely in the form of machine-executable object code generated by
17 a source language processor.
18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 27 Authors:
28 Alexandru Ermicioi
29 **/30 moduleaermicioi.aedi_property_reader.arg.accessor;
31 32 importaermicioi.aedi.exception.not_found_exception;
33 importaermicioi.aedi_property_reader.core.accessor;
34 importstd.algorithm;
35 importstd.array;
36 importstd.string;
37 importstd.conv;
38 importstd.range;
39 40 /**
41 Accessor filtering a list of strings out of strings that are not containing a command line property
42 **/43 classArgumentAccessor : PropertyAccessor!(const(string)[]) {
44 45 privatestaticstructFilter {
46 stringproperty;
47 48 const(string)[] component;
49 const(string)[] buff;
50 51 nothrow {
52 this(const(string)[] component, stringproperty) {
53 this.component = component;
54 this.property = property;
55 take(1);
56 }
57 58 Filtersave() {
59 returnthis;
60 }
61 62 stringfront() {
63 64 returnbuff[0];
65 }
66 67 voidpopFront() {
68 if (buff.length > 1) {
69 70 buff = buff.drop(1);
71 return;
72 }
73 74 if (buff.length > 0) {
75 76 buff = buff.drop(1);
77 this.advance;
78 }
79 }
80 81 boolempty() {
82 returnbuff.empty && component.empty;
83 }
84 85 privatevoidtake(size_tamount = 1) {
86 buff = (component.length >= amount) ? component.take(amount) : component.take(component.length);
87 component = (component.length >= amount) ? component.drop(amount) : component.drop(component.length);
88 }
89 90 privatevoidadvance() {
91 while (!component.empty) {
92 try {
93 94 if (component.front.commonPrefix("--").equal("--")) {
95 autosplitted = component.front.splitter("=");
96 97 if ((splitted.front.strip('-') == property) && !splitted.take(1).empty) {
98 take(1);
99 return;
100 }
101 102 if ((component.length > 1) && (splitted.front.strip('-') == property) && splitted.drop(1).front.commonPrefix("--").empty) {
103 take(2);
104 return;
105 }
106 }
107 108 if (component.front.commonPrefix("--").equal("-")) {
109 importstd.stdio;
110 111 if ((component.front.strip('-').equal(property)) || ((property.length == 1) && component.front.strip('-').canFind(property))) {
112 take(1);
113 return;
114 }
115 }
116 117 if (!component.front.splitter("=").drop(1).empty && component.front.splitter("=").front.equal(property)) {
118 take(1);
119 return;
120 }
121 122 if (property.isNumeric) {
123 autoup = property.to!size_t;
124 size_tcurrent;
125 126 autocount = component.countUntil!(c => c.commonPrefix("--").empty && c.splitter("=").drop(1).empty && (current++ == up));
127 component = component.drop(count);
128 take(1);
129 component = null;
130 return;
131 }
132 133 component = component.empty ? component : component.drop(1);
134 } catch (Exceptione) {
135 assert(false, text("Could not filter out command line arguments for ", property));
136 }
137 }
138 }
139 }
140 }
141 142 /**
143 Get a property out of component
144 145 Params:
146 component = a component which has some properties identified by property.
147 Throws:
148 NotFoundException in case when no requested property is available.
149 InvalidArgumentException in case when passed arguments are somehow invalid for use.
150 Returns:
151 FieldType accessed property.
152 **/153 const(string)[] access(const(string)[] component, stringproperty) const {
154 if (property.empty) {
155 returncomponent;
156 }
157 158 returnFilter(component, property).array;
159 }
160 161 /**
162 Check if requested property is present in component.
163 164 Check if requested property is present in component.
165 The method could have allocation side effects due to the fact that
166 it is not restricted in calling access method of the accessor.
167 168 Params:
169 component = component which is supposed to have property
170 property = speculated property that is to be tested if it is present in component
171 Returns:
172 true if property is in component
173 **/174 boolhas(inconst(string)[] component, stringproperty) constnothrow {
175 importstd.experimental.logger;
176 importaermicioi.aedi_property_reader.core.traits;
177 // debug(trace) trace(property, " ----------------------- ", component, Filter(component, property)).n;178 if (component.length > 1) {
179 180 return !Filter(component, property).drop(1).empty;
181 }
182 183 returnfalse;
184 }
185 186 /**
187 Identify the type of supported component.
188 189 Identify the type of supported component. It returns type info of component
190 if it is supported by accessor, otherwise it will return typeid(void) denoting that
191 the type isn't supported by accessor. The accessor is not limited to returning the type
192 info of passed component, it can actually return type info of super type or any type
193 given the returned type is implicitly convertible or castable to ComponentType.
194 195 Params:
196 component = the component for which accessor should identify the underlying type
197 198 Returns:
199 TypeInfo type information about passed component, or typeid(void) if component is not supported.
200 **/201 TypeInfocomponentType(const(string)[] component) constnothrow {
202 returntypeid(const(string)[]);
203 }
204 }