From 1bf4328843d114f30e900a66c7ca1053f90afc1e Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Mon, 1 Jan 2018 14:40:01 -0800 Subject: Make IntermediateField Set() method type-safe --- src/WixToolset.Data/IntermediateFieldExtensions.cs | 419 +++++++++++++++------ src/WixToolset.Data/IntermediateTupleExtensions.cs | 81 +++- .../Tuples/WixBundlePackageTuple.cs | 4 +- .../Tuples/WixBundlePayloadTuple.cs | 2 +- 4 files changed, 383 insertions(+), 123 deletions(-) diff --git a/src/WixToolset.Data/IntermediateFieldExtensions.cs b/src/WixToolset.Data/IntermediateFieldExtensions.cs index 89a6b903..6bc82b37 100644 --- a/src/WixToolset.Data/IntermediateFieldExtensions.cs +++ b/src/WixToolset.Data/IntermediateFieldExtensions.cs @@ -9,117 +9,6 @@ namespace WixToolset.Data [ThreadStatic] internal static string valueContext; - public static IntermediateField Set(this IntermediateField field, object value) - { - var data = value; - - if (field == null) - { - throw new ArgumentNullException(nameof(field)); - } - else if (value == null) - { - // Null is always allowed. - } - else if (field.Type == IntermediateFieldType.String && !(value is string)) - { - if (value is int) - { - data = value.ToString(); - } - else if (value is bool b) - { - data = b ? "true" : "false"; - } - else - { - throw new ArgumentException(nameof(value)); - } - } - else if (field.Type == IntermediateFieldType.Number && !(value is int)) - { - if (value is string str && Int32.TryParse(str, out var number)) - { - data = number; - } - else - { - throw new ArgumentException(nameof(value)); - } - } - else if (field.Type == IntermediateFieldType.Bool && !(value is bool)) - { - if (value is int) - { - data = ((int)value) != 0; - } - else if (value is string str) - { - if (str.Equals("yes", StringComparison.OrdinalIgnoreCase) || str.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - data = true; - } - else if (str.Equals("no", StringComparison.OrdinalIgnoreCase) || str.Equals("false", StringComparison.OrdinalIgnoreCase)) - { - data = false; - } - else - { - throw new ArgumentException(nameof(value)); - } - } - else - { - throw new ArgumentException(nameof(value)); - } - } - else if (field.Type == IntermediateFieldType.Path && !(value is IntermediateFieldPathValue)) - { - if (value is string str) - { - data = new IntermediateFieldPathValue { Path = str }; - } - else - { - throw new ArgumentException(nameof(value)); - } - } - else if (field.Type == IntermediateFieldType.LargeNumber && !(value is long)) - { - if (value is string str && Int64.TryParse(str, out var number)) - { - data = number; - } - else if (value is int i) - { - data = (long)i; - } - else - { - throw new ArgumentException(nameof(value)); - } - } - - field.Value = new IntermediateFieldValue - { - Context = valueContext, - Data = data, - PreviousValue = field.Value - }; - - return field; - } - - public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, object value) - { - if (field == null) - { - field = new IntermediateField(definition); - } - - return field.Set(value); - } - public static bool AsBool(this IntermediateField field) { if (field == null || field.Value == null || field.Value.Data == null) @@ -261,5 +150,313 @@ namespace WixToolset.Data throw new InvalidCastException($"Cannot convert field {field.Name} with type {field.Type} to string"); } } + + public static IntermediateField Set(this IntermediateField field, bool value) + { + object data; + + if (field == null) + { + throw new ArgumentNullException(nameof(field)); + } + + switch (field.Type) + { + case IntermediateFieldType.Bool: + data = value; + break; + + case IntermediateFieldType.LargeNumber: + data = value ? (long)1 : (long)0; + break; + + case IntermediateFieldType.Number: + data = value ? 1 : 0; + break; + + case IntermediateFieldType.Path: + throw new ArgumentException($"Cannot convert bool '{value}' to a 'Path' field type.", nameof(value)); + + case IntermediateFieldType.String: + data = value ? "true" : "false"; + break; + + default: + throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}"); + }; + + return AssignFieldValue(field, data); + } + + public static IntermediateField Set(this IntermediateField field, bool? value) + { + if (field == null) + { + throw new ArgumentNullException(nameof(field)); + } + + return value.HasValue ? field.Set(value.Value) : AssignFieldValue(field, null); + } + + public static IntermediateField Set(this IntermediateField field, long value) + { + object data; + + if (field == null) + { + throw new ArgumentNullException(nameof(field)); + } + + switch (field.Type) + { + case IntermediateFieldType.Bool: + data = (value != 0); + break; + + case IntermediateFieldType.LargeNumber: + data = value; + break; + + case IntermediateFieldType.Number: + data = (int)value; + break; + + case IntermediateFieldType.Path: + throw new ArgumentException($"Cannot convert large number '{value}' to a 'Path' field type.", nameof(value)); + + case IntermediateFieldType.String: + data = value.ToString(); + break; + + default: + throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}"); + }; + + return AssignFieldValue(field, data); + } + + public static IntermediateField Set(this IntermediateField field, long? value) + { + if (field == null) + { + throw new ArgumentNullException(nameof(field)); + } + + return value.HasValue ? field.Set(value.Value) : AssignFieldValue(field, null); + } + + public static IntermediateField Set(this IntermediateField field, int value) + { + object data; + + if (field == null) + { + throw new ArgumentNullException(nameof(field)); + } + + switch (field.Type) + { + case IntermediateFieldType.Bool: + data = (value != 0); + break; + + case IntermediateFieldType.LargeNumber: + data = (long)value; + break; + + case IntermediateFieldType.Number: + data = value; + break; + + case IntermediateFieldType.Path: + throw new ArgumentException($"Cannot convert number '{value}' to a 'Path' field type.", nameof(value)); + + case IntermediateFieldType.String: + data = value.ToString(); + break; + + default: + throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}"); + }; + + return AssignFieldValue(field, data); + } + + public static IntermediateField Set(this IntermediateField field, int? value) + { + if (field == null) + { + throw new ArgumentNullException(nameof(field)); + } + + return value.HasValue ? field.Set(value.Value) : AssignFieldValue(field, null); + } + + public static IntermediateField Set(this IntermediateField field, IntermediateFieldPathValue value) + { + object data; + + if (field == null) + { + throw new ArgumentNullException(nameof(field)); + } + else if (value == null) // null is always allowed. + { + data = null; + } + else + { + switch (field.Type) + { + case IntermediateFieldType.Bool: + throw new ArgumentException($"Cannot convert path '{value.Path}' to a 'bool' field type.", nameof(value)); + + case IntermediateFieldType.LargeNumber: + throw new ArgumentException($"Cannot convert path '{value.Path}' to a 'large number' field type.", nameof(value)); + + case IntermediateFieldType.Number: + throw new ArgumentException($"Cannot convert path '{value.Path}' to a 'number' field type.", nameof(value)); + + case IntermediateFieldType.Path: + data = value; + break; + + case IntermediateFieldType.String: + data = value.Path; + break; + + default: + throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}"); + }; + } + + return AssignFieldValue(field, data); + } + + public static IntermediateField Set(this IntermediateField field, string value) + { + object data; + + if (field == null) + { + throw new ArgumentNullException(nameof(field)); + } + else if (value == null) // Null is always allowed. + { + data = null; + } + else + { + switch (field.Type) + { + case IntermediateFieldType.Bool: + if (value.Equals("yes", StringComparison.OrdinalIgnoreCase) || value.Equals("true", StringComparison.OrdinalIgnoreCase)) + { + data = true; + } + else if (value.Equals("no", StringComparison.OrdinalIgnoreCase) || value.Equals("false", StringComparison.OrdinalIgnoreCase)) + { + data = false; + } + else + { + throw new ArgumentException($"Cannot convert string '{value}' to a 'bool' field type.", nameof(value)); + } + break; + + case IntermediateFieldType.LargeNumber: + if (Int64.TryParse(value, out var largeNumber)) + { + data = largeNumber; + } + else + { + throw new ArgumentException($"Cannot convert string '{value}' to a 'large number' field type.", nameof(value)); + } + break; + + case IntermediateFieldType.Number: + if (Int32.TryParse(value, out var number)) + { + data = number; + } + else + { + throw new ArgumentException($"Cannot convert string '{value}' to a 'number' field type.", nameof(value)); + } + break; + + case IntermediateFieldType.Path: + data = new IntermediateFieldPathValue { Path = value }; + break; + + case IntermediateFieldType.String: + data = value; + break; + + default: + throw new ArgumentOutOfRangeException(nameof(value), $"Unknown intermediate field type: {value.GetType()}"); + }; + } + + return AssignFieldValue(field, data); + } + + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, bool value) + { + return EnsureField(field, definition).Set(value); + } + + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, bool? value) + { + return EnsureField(field, definition).Set(value); + } + + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, long value) + { + return EnsureField(field, definition).Set(value); + } + + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, long? value) + { + return EnsureField(field, definition).Set(value); + } + + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, int value) + { + return EnsureField(field, definition).Set(value); + } + + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, int? value) + { + return EnsureField(field, definition).Set(value); + } + + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, IntermediateFieldPathValue value) + { + return EnsureField(field, definition).Set(value); + } + + public static IntermediateField Set(this IntermediateField field, IntermediateFieldDefinition definition, string value) + { + return EnsureField(field, definition).Set(value); + } + + private static IntermediateField AssignFieldValue(IntermediateField field, object data) + { + field.Value = new IntermediateFieldValue + { + Context = valueContext, + Data = data, + PreviousValue = field.Value + }; + + return field; + } + + private static IntermediateField EnsureField(IntermediateField field, IntermediateFieldDefinition definition) + { + return field ?? new IntermediateField(definition); + } } } diff --git a/src/WixToolset.Data/IntermediateTupleExtensions.cs b/src/WixToolset.Data/IntermediateTupleExtensions.cs index 615c21f9..f5b30d47 100644 --- a/src/WixToolset.Data/IntermediateTupleExtensions.cs +++ b/src/WixToolset.Data/IntermediateTupleExtensions.cs @@ -4,15 +4,6 @@ namespace WixToolset.Data { public static class IntermediateTupleExtensions { - public static IntermediateField Set(this IntermediateTuple tuple, int index, object value) - { - var definition = tuple.Definition.FieldDefinitions[index]; - - var field = tuple.Fields[index].Set(definition, value); - - return tuple.Fields[index] = field; - } - public static bool AsBool(this IntermediateTuple tuple, int index) { return tuple?.Fields[index].AsBool() ?? false; @@ -37,5 +28,77 @@ namespace WixToolset.Data { return tuple?.Fields[index].AsString(); } + + public static IntermediateField Set(this IntermediateTuple tuple, int index, bool value) + { + var definition = tuple.Definition.FieldDefinitions[index]; + + var field = tuple.Fields[index].Set(definition, value); + + return tuple.Fields[index] = field; + } + + public static IntermediateField Set(this IntermediateTuple tuple, int index, bool? value) + { + var definition = tuple.Definition.FieldDefinitions[index]; + + var field = tuple.Fields[index].Set(definition, value); + + return tuple.Fields[index] = field; + } + + public static IntermediateField Set(this IntermediateTuple tuple, int index, long value) + { + var definition = tuple.Definition.FieldDefinitions[index]; + + var field = tuple.Fields[index].Set(definition, value); + + return tuple.Fields[index] = field; + } + + public static IntermediateField Set(this IntermediateTuple tuple, int index, long? value) + { + var definition = tuple.Definition.FieldDefinitions[index]; + + var field = tuple.Fields[index].Set(definition, value); + + return tuple.Fields[index] = field; + } + + public static IntermediateField Set(this IntermediateTuple tuple, int index, int value) + { + var definition = tuple.Definition.FieldDefinitions[index]; + + var field = tuple.Fields[index].Set(definition, value); + + return tuple.Fields[index] = field; + } + + public static IntermediateField Set(this IntermediateTuple tuple, int index, int? value) + { + var definition = tuple.Definition.FieldDefinitions[index]; + + var field = tuple.Fields[index].Set(definition, value); + + return tuple.Fields[index] = field; + } + + public static IntermediateField Set(this IntermediateTuple tuple, int index, IntermediateFieldPathValue value) + { + var definition = tuple.Definition.FieldDefinitions[index]; + + var field = tuple.Fields[index].Set(definition, value); + + return tuple.Fields[index] = field; + } + + public static IntermediateField Set(this IntermediateTuple tuple, int index, string value) + { + var definition = tuple.Definition.FieldDefinitions[index]; + + var field = tuple.Fields[index].Set(definition, value); + + return tuple.Fields[index] = field; + } } } diff --git a/src/WixToolset.Data/Tuples/WixBundlePackageTuple.cs b/src/WixToolset.Data/Tuples/WixBundlePackageTuple.cs index e0eedce1..eaf7ef92 100644 --- a/src/WixToolset.Data/Tuples/WixBundlePackageTuple.cs +++ b/src/WixToolset.Data/Tuples/WixBundlePackageTuple.cs @@ -126,7 +126,7 @@ namespace WixToolset.Data.Tuples public YesNoAlwaysType Cache { get => Enum.TryParse((string)this.Fields[(int)WixBundlePackageTupleFields.Cache]?.Value, true, out YesNoAlwaysType value) ? value : YesNoAlwaysType.NotSet; - set => this.Set((int)WixBundlePackageTupleFields.Cache, value); + set => this.Set((int)WixBundlePackageTupleFields.Cache, value.ToString().ToLowerInvariant()); } public string CacheId @@ -144,7 +144,7 @@ namespace WixToolset.Data.Tuples public YesNoDefaultType PerMachine { get => Enum.TryParse((string)this.Fields[(int)WixBundlePackageTupleFields.PerMachine]?.Value, true, out YesNoDefaultType value) ? value : YesNoDefaultType.NotSet; - set => this.Set((int)WixBundlePackageTupleFields.PerMachine, value); + set => this.Set((int)WixBundlePackageTupleFields.PerMachine, value.ToString().ToLowerInvariant()); } public string LogPathVariable diff --git a/src/WixToolset.Data/Tuples/WixBundlePayloadTuple.cs b/src/WixToolset.Data/Tuples/WixBundlePayloadTuple.cs index d1c02387..d2a82f93 100644 --- a/src/WixToolset.Data/Tuples/WixBundlePayloadTuple.cs +++ b/src/WixToolset.Data/Tuples/WixBundlePayloadTuple.cs @@ -106,7 +106,7 @@ namespace WixToolset.Data.Tuples public YesNoDefaultType Compressed { get => Enum.TryParse((string)this.Fields[(int)WixBundlePayloadTupleFields.Compressed]?.Value, true, out YesNoDefaultType value) ? value : YesNoDefaultType.NotSet; - set => this.Set((int)WixBundlePayloadTupleFields.Compressed, value); + set => this.Set((int)WixBundlePayloadTupleFields.Compressed, value.ToString().ToLowerInvariant()); } public string UnresolvedSourceFile -- cgit v1.2.3-55-g6feb