@joebigelow / wix / commits / 1bf43288

Make IntermediateField Set() method type-safe

Rob Mensching committed Jan 1, 2018 at 14:40 UTC 1bf4328843d114f30e900a66c7ca1053f90afc1e
4 files changed +383 -123
src/WixToolset.Data/IntermediateFieldExtensions.cs
+308 -111
@@ -9,117 +9,6 @@ namespace WixToolset.Data
9 [ThreadStatic]
10 internal static string valueContext;
11
12 - public static IntermediateField Set(this IntermediateField field, object value)
13 - {
14 - var data = value;
15 -
16 - if (field == null)
17 - {
18 - throw new ArgumentNullException(nameof(field));
19 - }
20 - else if (value == null)
21 - {
22 - // Null is always allowed.
23 - }
24 - else if (field.Type == IntermediateFieldType.String && !(value is string))
25 - {
26 - if (value is int)
27 - {
28 - data = value.ToString();
29 - }
30 - else if (value is bool b)
31 - {
32 - data = b ? "true" : "false";
33 - }
34 - else
35 - {
36 - throw new ArgumentException(nameof(value));
37 - }
38 - }
39 - else if (field.Type == IntermediateFieldType.Number && !(value is int))
40 - {
41 - if (value is string str && Int32.TryParse(str, out var number))
42 - {
43 - data = number;
44 - }
45 - else
46 - {
47 - throw new ArgumentException(nameof(value));
48 - }
49 - }
50 - else if (field.Type == IntermediateFieldType.Bool && !(value is bool))
51 - {
52 - if (value is int)
53 - {
54 - data = ((int)value) != 0;
55 - }
56 - else if (value is string str)
57 - {
58 - if (str.Equals("yes", StringComparison.OrdinalIgnoreCase) || str.Equals("true", StringComparison.OrdinalIgnoreCase))
59 - {
60 - data = true;
61 - }
62 - else if (str.Equals("no", StringComparison.OrdinalIgnoreCase) || str.Equals("false", StringComparison.OrdinalIgnoreCase))
63 - {
64 - data = false;
65 - }
66 - else
67 - {
68 - throw new ArgumentException(nameof(value));
69 - }
70 - }
71 - else
72 - {
73 - throw new ArgumentException(nameof(value));
74 - }
75 - }
76 - else if (field.Type == IntermediateFieldType.Path && !(value is IntermediateFieldPathValue))
77 - {
78 - if (value is string str)
79 - {
80 - data = new IntermediateFieldPathValue { Path = str };
81 - }
82 - else
83 - {
84 - throw new ArgumentException(nameof(value));
85 - }
86 - }
87 - else if (field.Type == IntermediateFieldType.LargeNumber && !(value is long))
88 - {
89 - if (value is string str && Int64.TryParse(str, out var number))
90 - {
91 - data = number;
92 - }
93 - else if (value is int i)
94 - {
95 - data = (long)i;
96 - }
97 - else
98 - {
99 - throw new ArgumentException(nameof(value));
100 - }
101 - }
102 -
103 - field.Value = new IntermediateFieldValue
104 - {
105 - Context = valueContext,
106 - Data = data,
107 - PreviousValue = field.Value
108 - };
109 -
110 - return field;
111 - }
112 -
113 - public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, object value)
114 - {
115 - if (field == null)
116 - {
117 - field = new IntermediateField(definition);
118 - }
119 -
120 - return field.Set(value);
121 - }
122 -
12 public static bool AsBool(this IntermediateField field)
13 {
14 if (field == null || field.Value == null || field.Value.Data == null)
@@ -261,5 +150,313 @@ namespace WixToolset.Data
150 throw new InvalidCastException($"Cannot convert field {field.Name} with type {field.Type} to string");
151 }
152 }
153 +
154 + public static IntermediateField Set(this IntermediateField field, bool value)
155 + {
156 + object data;
157 +
158 + if (field == null)
159 + {
160 + throw new ArgumentNullException(nameof(field));
161 + }
162 +
163 + switch (field.Type)
164 + {
165 + case IntermediateFieldType.Bool:
166 + data = value;
167 + break;
168 +
169 + case IntermediateFieldType.LargeNumber:
170 + data = value ? (long)1 : (long)0;
171 + break;
172 +
173 + case IntermediateFieldType.Number:
174 + data = value ? 1 : 0;
175 + break;
176 +
177 + case IntermediateFieldType.Path:
178 + throw new ArgumentException($"Cannot convert bool '{value}' to a 'Path' field type.", nameof(value));
179 +
180 + case IntermediateFieldType.String:
181 + data = value ? "true" : "false";
182 + break;
183 +
184 + default:
185 + throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}");
186 + };
187 +
188 + return AssignFieldValue(field, data);
189 + }
190 +
191 + public static IntermediateField Set(this IntermediateField field, bool? value)
192 + {
193 + if (field == null)
194 + {
195 + throw new ArgumentNullException(nameof(field));
196 + }
197 +
198 + return value.HasValue ? field.Set(value.Value) : AssignFieldValue(field, null);
199 + }
200 +
201 + public static IntermediateField Set(this IntermediateField field, long value)
202 + {
203 + object data;
204 +
205 + if (field == null)
206 + {
207 + throw new ArgumentNullException(nameof(field));
208 + }
209 +
210 + switch (field.Type)
211 + {
212 + case IntermediateFieldType.Bool:
213 + data = (value != 0);
214 + break;
215 +
216 + case IntermediateFieldType.LargeNumber:
217 + data = value;
218 + break;
219 +
220 + case IntermediateFieldType.Number:
221 + data = (int)value;
222 + break;
223 +
224 + case IntermediateFieldType.Path:
225 + throw new ArgumentException($"Cannot convert large number '{value}' to a 'Path' field type.", nameof(value));
226 +
227 + case IntermediateFieldType.String:
228 + data = value.ToString();
229 + break;
230 +
231 + default:
232 + throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}");
233 + };
234 +
235 + return AssignFieldValue(field, data);
236 + }
237 +
238 + public static IntermediateField Set(this IntermediateField field, long? value)
239 + {
240 + if (field == null)
241 + {
242 + throw new ArgumentNullException(nameof(field));
243 + }
244 +
245 + return value.HasValue ? field.Set(value.Value) : AssignFieldValue(field, null);
246 + }
247 +
248 + public static IntermediateField Set(this IntermediateField field, int value)
249 + {
250 + object data;
251 +
252 + if (field == null)
253 + {
254 + throw new ArgumentNullException(nameof(field));
255 + }
256 +
257 + switch (field.Type)
258 + {
259 + case IntermediateFieldType.Bool:
260 + data = (value != 0);
261 + break;
262 +
263 + case IntermediateFieldType.LargeNumber:
264 + data = (long)value;
265 + break;
266 +
267 + case IntermediateFieldType.Number:
268 + data = value;
269 + break;
270 +
271 + case IntermediateFieldType.Path:
272 + throw new ArgumentException($"Cannot convert number '{value}' to a 'Path' field type.", nameof(value));
273 +
274 + case IntermediateFieldType.String:
275 + data = value.ToString();
276 + break;
277 +
278 + default:
279 + throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}");
280 + };
281 +
282 + return AssignFieldValue(field, data);
283 + }
284 +
285 + public static IntermediateField Set(this IntermediateField field, int? value)
286 + {
287 + if (field == null)
288 + {
289 + throw new ArgumentNullException(nameof(field));
290 + }
291 +
292 + return value.HasValue ? field.Set(value.Value) : AssignFieldValue(field, null);
293 + }
294 +
295 + public static IntermediateField Set(this IntermediateField field, IntermediateFieldPathValue value)
296 + {
297 + object data;
298 +
299 + if (field == null)
300 + {
301 + throw new ArgumentNullException(nameof(field));
302 + }
303 + else if (value == null) // null is always allowed.
304 + {
305 + data = null;
306 + }
307 + else
308 + {
309 + switch (field.Type)
310 + {
311 + case IntermediateFieldType.Bool:
312 + throw new ArgumentException($"Cannot convert path '{value.Path}' to a 'bool' field type.", nameof(value));
313 +
314 + case IntermediateFieldType.LargeNumber:
315 + throw new ArgumentException($"Cannot convert path '{value.Path}' to a 'large number' field type.", nameof(value));
316 +
317 + case IntermediateFieldType.Number:
318 + throw new ArgumentException($"Cannot convert path '{value.Path}' to a 'number' field type.", nameof(value));
319 +
320 + case IntermediateFieldType.Path:
321 + data = value;
322 + break;
323 +
324 + case IntermediateFieldType.String:
325 + data = value.Path;
326 + break;
327 +
328 + default:
329 + throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}");
330 + };
331 + }
332 +
333 + return AssignFieldValue(field, data);
334 + }
335 +
336 + public static IntermediateField Set(this IntermediateField field, string value)
337 + {
338 + object data;
339 +
340 + if (field == null)
341 + {
342 + throw new ArgumentNullException(nameof(field));
343 + }
344 + else if (value == null) // Null is always allowed.
345 + {
346 + data = null;
347 + }
348 + else
349 + {
350 + switch (field.Type)
351 + {
352 + case IntermediateFieldType.Bool:
353 + if (value.Equals("yes", StringComparison.OrdinalIgnoreCase) || value.Equals("true", StringComparison.OrdinalIgnoreCase))
354 + {
355 + data = true;
356 + }
357 + else if (value.Equals("no", StringComparison.OrdinalIgnoreCase) || value.Equals("false", StringComparison.OrdinalIgnoreCase))
358 + {
359 + data = false;
360 + }
361 + else
362 + {
363 + throw new ArgumentException($"Cannot convert string '{value}' to a 'bool' field type.", nameof(value));
364 + }
365 + break;
366 +
367 + case IntermediateFieldType.LargeNumber:
368 + if (Int64.TryParse(value, out var largeNumber))
369 + {
370 + data = largeNumber;
371 + }
372 + else
373 + {
374 + throw new ArgumentException($"Cannot convert string '{value}' to a 'large number' field type.", nameof(value));
375 + }
376 + break;
377 +
378 + case IntermediateFieldType.Number:
379 + if (Int32.TryParse(value, out var number))
380 + {
381 + data = number;
382 + }
383 + else
384 + {
385 + throw new ArgumentException($"Cannot convert string '{value}' to a 'number' field type.", nameof(value));
386 + }
387 + break;
388 +
389 + case IntermediateFieldType.Path:
390 + data = new IntermediateFieldPathValue { Path = value };
391 + break;
392 +
393 + case IntermediateFieldType.String:
394 + data = value;
395 + break;
396 +
397 + default:
398 + throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}");
399 + };
400 + }
401 +
402 + return AssignFieldValue(field, data);
403 + }
404 +
405 + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, bool value)
406 + {
407 + return EnsureField(field, definition).Set(value);
408 + }
409 +
410 + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, bool? value)
411 + {
412 + return EnsureField(field, definition).Set(value);
413 + }
414 +
415 + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, long value)
416 + {
417 + return EnsureField(field, definition).Set(value);
418 + }
419 +
420 + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, long? value)
421 + {
422 + return EnsureField(field, definition).Set(value);
423 + }
424 +
425 + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, int value)
426 + {
427 + return EnsureField(field, definition).Set(value);
428 + }
429 +
430 + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, int? value)
431 + {
432 + return EnsureField(field, definition).Set(value);
433 + }
434 +
435 + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, IntermediateFieldPathValue value)
436 + {
437 + return EnsureField(field, definition).Set(value);
438 + }
439 +
440 + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, string value)
441 + {
442 + return EnsureField(field, definition).Set(value);
443 + }
444 +
445 + private static IntermediateField AssignFieldValue(IntermediateField field, object data)
446 + {
447 + field.Value = new IntermediateFieldValue
448 + {
449 + Context = valueContext,
450 + Data = data,
451 + PreviousValue = field.Value
452 + };
453 +
454 + return field;
455 + }
456 +
457 + private static IntermediateField EnsureField(IntermediateField field, IntermediateFieldDefinition definition)
458 + {
459 + return field ?? new IntermediateField(definition);
460 + }
461 }
462 }
src/WixToolset.Data/IntermediateTupleExtensions.cs
+72 -9
@@ -4,15 +4,6 @@ namespace WixToolset.Data
4 {
5 public static class IntermediateTupleExtensions
6 {
7 - public static IntermediateField Set(this IntermediateTuple tuple, int index, object value)
8 - {
9 - var definition = tuple.Definition.FieldDefinitions[index];
10 -
11 - var field = tuple.Fields[index].Set(definition, value);
12 -
13 - return tuple.Fields[index] = field;
14 - }
15 -
7 public static bool AsBool(this IntermediateTuple tuple, int index)
8 {
9 return tuple?.Fields[index].AsBool() ?? false;
@@ -37,5 +28,77 @@ namespace WixToolset.Data
28 {
29 return tuple?.Fields[index].AsString();
30 }
31 +
32 + public static IntermediateField Set(this IntermediateTuple tuple, int index, bool value)
33 + {
34 + var definition = tuple.Definition.FieldDefinitions[index];
35 +
36 + var field = tuple.Fields[index].Set(definition, value);
37 +
38 + return tuple.Fields[index] = field;
39 + }
40 +
41 + public static IntermediateField Set(this IntermediateTuple tuple, int index, bool? value)
42 + {
43 + var definition = tuple.Definition.FieldDefinitions[index];
44 +
45 + var field = tuple.Fields[index].Set(definition, value);
46 +
47 + return tuple.Fields[index] = field;
48 + }
49 +
50 + public static IntermediateField Set(this IntermediateTuple tuple, int index, long value)
51 + {
52 + var definition = tuple.Definition.FieldDefinitions[index];
53 +
54 + var field = tuple.Fields[index].Set(definition, value);
55 +
56 + return tuple.Fields[index] = field;
57 + }
58 +
59 + public static IntermediateField Set(this IntermediateTuple tuple, int index, long? value)
60 + {
61 + var definition = tuple.Definition.FieldDefinitions[index];
62 +
63 + var field = tuple.Fields[index].Set(definition, value);
64 +
65 + return tuple.Fields[index] = field;
66 + }
67 +
68 + public static IntermediateField Set(this IntermediateTuple tuple, int index, int value)
69 + {
70 + var definition = tuple.Definition.FieldDefinitions[index];
71 +
72 + var field = tuple.Fields[index].Set(definition, value);
73 +
74 + return tuple.Fields[index] = field;
75 + }
76 +
77 + public static IntermediateField Set(this IntermediateTuple tuple, int index, int? value)
78 + {
79 + var definition = tuple.Definition.FieldDefinitions[index];
80 +
81 + var field = tuple.Fields[index].Set(definition, value);
82 +
83 + return tuple.Fields[index] = field;
84 + }
85 +
86 + public static IntermediateField Set(this IntermediateTuple tuple, int index, IntermediateFieldPathValue value)
87 + {
88 + var definition = tuple.Definition.FieldDefinitions[index];
89 +
90 + var field = tuple.Fields[index].Set(definition, value);
91 +
92 + return tuple.Fields[index] = field;
93 + }
94 +
95 + public static IntermediateField Set(this IntermediateTuple tuple, int index, string value)
96 + {
97 + var definition = tuple.Definition.FieldDefinitions[index];
98 +
99 + var field = tuple.Fields[index].Set(definition, value);
100 +
101 + return tuple.Fields[index] = field;
102 + }
103 }
104 }
src/WixToolset.Data/Tuples/WixBundlePackageTuple.cs
+2 -2
@@ -126,7 +126,7 @@ namespace WixToolset.Data.Tuples
126 public YesNoAlwaysType Cache
127 {
128 get => Enum.TryParse((string)this.Fields[(int)WixBundlePackageTupleFields.Cache]?.Value, true, out YesNoAlwaysType value) ? value : YesNoAlwaysType.NotSet;
129 - set => this.Set((int)WixBundlePackageTupleFields.Cache, value);
129 + set => this.Set((int)WixBundlePackageTupleFields.Cache, value.ToString().ToLowerInvariant());
130 }
131
132 public string CacheId
@@ -144,7 +144,7 @@ namespace WixToolset.Data.Tuples
144 public YesNoDefaultType PerMachine
145 {
146 get => Enum.TryParse((string)this.Fields[(int)WixBundlePackageTupleFields.PerMachine]?.Value, true, out YesNoDefaultType value) ? value : YesNoDefaultType.NotSet;
147 - set => this.Set((int)WixBundlePackageTupleFields.PerMachine, value);
147 + set => this.Set((int)WixBundlePackageTupleFields.PerMachine, value.ToString().ToLowerInvariant());
148 }
149
150 public string LogPathVariable
src/WixToolset.Data/Tuples/WixBundlePayloadTuple.cs
+1 -1
@@ -106,7 +106,7 @@ namespace WixToolset.Data.Tuples
106 public YesNoDefaultType Compressed
107 {
108 get => Enum.TryParse((string)this.Fields[(int)WixBundlePayloadTupleFields.Compressed]?.Value, true, out YesNoDefaultType value) ? value : YesNoDefaultType.NotSet;
109 - set => this.Set((int)WixBundlePayloadTupleFields.Compressed, value);
109 + set => this.Set((int)WixBundlePayloadTupleFields.Compressed, value.ToString().ToLowerInvariant());
110 }
111
112 public string UnresolvedSourceFile