static void AssertType(PartialFieldType expected, PartialFieldType actual) { Assert.AreEqual(expected.Name, actual.Name, "Field type names didn't match."); Assert.AreEqual(expected.Generics.Count, actual.Generics.Count, "Field type's generic are not the same count."); Assert.AreEqual(expected.Meta.Count, actual.Meta.Count, "Field type's meta are not the same count."); foreach (var(i, expectedGeneric) in expected.Generics) { AssertType(expectedGeneric, actual.Generics[i]); } foreach (var(metaName, expectedMeta) in expected.Meta) { if (expectedMeta is Regex expectedRegex) { if (actual.Meta[metaName] is Regex actualRegex) { Assert.AreEqual(expectedRegex.ToString(), actualRegex.ToString(), $"Field type meta '{ metaName }' didn't match"); Assert.AreEqual(expectedRegex.Options, actualRegex.Options, $"Field type meta '{ metaName }' didn't match"); } else { Assert.Fail($"Field type meta '{ metaName }' didn't match"); } } else { Assert.AreEqual(expectedMeta, actual.Meta[metaName], $"Field type meta '{ metaName }' didn't match"); } } }
static void ModifierToNotSameAsMeta(PartialFieldType fieldType, ObganismModifier obganismModifier) { if (GetModifierParameterStringValue(obganismModifier, 0) is string stringValue) { fieldType.Meta[NapBuiltInMeta.NotSameAs] = stringValue; } }
static void ModifierParameterToIsInclusiveMeta(PartialFieldType fieldType, ObganismModifier obganismModifier, int parameterIndex, string metaName, bool defaultInclusivity) { var explicitInclusivity = GetModifierParameterStringValue(obganismModifier, parameterIndex); fieldType.Meta[metaName] = explicitInclusivity != null ? explicitInclusivity.StartsWith("in", StringComparison.InvariantCultureIgnoreCase) : defaultInclusivity; }
static void ModifierParameterToMinMaxMeta(PartialFieldType fieldType, ObganismModifier obganismModifier, int parameterIndex, string metaName) { fieldType.Meta[metaName] = fieldType.Name switch { NapBuiltInTypes.Float => GetModifierParameterFloatValue(obganismModifier, parameterIndex), NapBuiltInTypes.Date => GetModifierParameterDateValue(obganismModifier, parameterIndex), NapBuiltInTypes.Datetime => GetModifierParameterDateTimeValue(obganismModifier, parameterIndex), NapBuiltInTypes.Duration => GetModifierParameterTimeSpanValue(obganismModifier, parameterIndex), _ => GetModifierParameterIntValue(obganismModifier, parameterIndex) }; }
static PartialFieldType GetMetaTargetGeneric(PartialFieldType fieldType) { var targetGenericIndex = fieldType.Name == NapBuiltInTypes.Map ? 1 : 0; if (!fieldType.Generics.TryGetValue(targetGenericIndex, out var targetGenericType)) { fieldType.Generics[targetGenericIndex] = targetGenericType = new PartialFieldType(); } return(targetGenericType); }
static void ModifierToPatternMeta(PartialFieldType fieldType, ObganismModifier obganismModifier) { if (GetModifierParameterStringValue(obganismModifier, 0) is string pattern) { fieldType.Meta[NapBuiltInMeta.Pattern] = new Regex( pattern, string.Equals(GetModifierParameterStringValue(obganismModifier, 1), "ignore case", StringComparison.InvariantCultureIgnoreCase) ? RegexOptions.IgnoreCase : RegexOptions.None ); } }
static void ModifierToDefaultMeta(PartialFieldType fieldType, ObganismModifier obganismModifier) { fieldType.Meta[NapBuiltInMeta.Default] = fieldType.Name switch { NapBuiltInTypes.Bool => GetModifierParameterBoolValue(obganismModifier, 0), NapBuiltInTypes.Int => GetModifierParameterIntValue(obganismModifier, 0), NapBuiltInTypes.Float => GetModifierParameterFloatValue(obganismModifier, 0), NapBuiltInTypes.Char => GetModifierParameterCharValue(obganismModifier, 0), NapBuiltInTypes.String => GetModifierParameterStringValue(obganismModifier, 0), NapBuiltInTypes.Date => GetModifierParameterDateValue(obganismModifier, 0), NapBuiltInTypes.Datetime => GetModifierParameterDateTimeValue(obganismModifier, 0), NapBuiltInTypes.Duration => GetModifierParameterTimeSpanValue(obganismModifier, 0), _ => GetModifierParameterValue(obganismModifier, 0) }; }
static PartialFieldType TypeToFieldType(ObganismType obganismType) { var fieldType = new PartialFieldType { Name = obganismType.Name }; var i = 0; foreach (var obganismGeneric in obganismType.Generics) { fieldType.Generics.Add(i++, TypeToFieldType(obganismGeneric)); } return(fieldType); }
static void ModifierToMinMaxMeta(PartialFieldType fieldType, ObganismModifier obganismModifier, bool defaultInclusivity) { // range(min, max) if (obganismModifier.Parameters.Count == 2) { ModifierParameterToMinMaxMeta(fieldType, obganismModifier, 0, NapBuiltInMeta.Min); ModifierParameterToMinMaxMeta(fieldType, obganismModifier, 1, NapBuiltInMeta.Max); fieldType.Meta[NapBuiltInMeta.MinIsInclusive] = fieldType.Meta[NapBuiltInMeta.MaxIsInclusive] = defaultInclusivity; } else if (obganismModifier.Parameters.Count == 3) { ModifierParameterToMinMaxMeta(fieldType, obganismModifier, 0, NapBuiltInMeta.Min); // range(min, min_inclusive, max) if (GetModifierParameterValue(obganismModifier, 1) is string minInclusivity) { fieldType.Meta[NapBuiltInMeta.MinIsInclusive] = minInclusivity.StartsWith("in", StringComparison.InvariantCultureIgnoreCase); ModifierParameterToMinMaxMeta(fieldType, obganismModifier, 2, NapBuiltInMeta.Max); fieldType.Meta[NapBuiltInMeta.MaxIsInclusive] = defaultInclusivity; } // range(min, max, max_inclusive) else { fieldType.Meta[NapBuiltInMeta.MinIsInclusive] = defaultInclusivity; ModifierParameterToMinMaxMeta(fieldType, obganismModifier, 1, NapBuiltInMeta.Max); ModifierParameterToIsInclusiveMeta(fieldType, obganismModifier, 2, NapBuiltInMeta.MaxIsInclusive, defaultInclusivity); } } // range(min, min_inclusive, max, max_inclusive) else if (4 <= obganismModifier.Parameters.Count) { ModifierParameterToMinMaxMeta(fieldType, obganismModifier, 0, NapBuiltInMeta.Min); ModifierParameterToIsInclusiveMeta(fieldType, obganismModifier, 1, NapBuiltInMeta.MinIsInclusive, defaultInclusivity); ModifierParameterToMinMaxMeta(fieldType, obganismModifier, 2, NapBuiltInMeta.Max); ModifierParameterToIsInclusiveMeta(fieldType, obganismModifier, 3, NapBuiltInMeta.MaxIsInclusive, defaultInclusivity); } }
static void ModifierToForbiddenValuesMeta(PartialFieldType fieldType, ObganismModifier obganismModifier) { if (obganismModifier.Parameters.Count != 0) { fieldType.Meta[NapBuiltInMeta.ForbiddenValues] = fieldType.Name switch { NapBuiltInTypes.Int => GetModifierParameterValues(obganismModifier, GetModifierParameterIntValue), NapBuiltInTypes.Float => GetModifierParameterValues(obganismModifier, GetModifierParameterFloatValue), NapBuiltInTypes.Char => GetModifierParameterValues(obganismModifier, GetModifierParameterCharValue), NapBuiltInTypes.String => GetModifierParameterValues(obganismModifier, GetModifierParameterStringValue), NapBuiltInTypes.Date => GetModifierParameterValues(obganismModifier, GetModifierParameterDateValue), NapBuiltInTypes.Datetime => GetModifierParameterValues(obganismModifier, GetModifierParameterDateTimeValue), NapBuiltInTypes.Duration => GetModifierParameterValues(obganismModifier, GetModifierParameterTimeSpanValue), _ => GetModifierParameterValues(obganismModifier, GetModifierParameterValue) } } ; }
static void ModifierToMaxMeta(PartialFieldType fieldType, ObganismModifier obganismModifier, bool defaultInclusivity) { ModifierParameterToMinMaxMeta(fieldType, obganismModifier, 0, NapBuiltInMeta.Max); ModifierParameterToIsInclusiveMeta(fieldType, obganismModifier, 1, NapBuiltInMeta.MaxIsInclusive, defaultInclusivity); }
// Modifiers to Meta // ---- static void ModifierToMeta(PartialFieldType fieldType, ObganismModifier obganismModifier) { switch (obganismModifier.Name) { // Built-in Meta // ---- case "min": case "at least": case "not below": case "not before": ModifierToMinMeta(fieldType, obganismModifier, true); break; case "above": case "after": ModifierToMinMeta(fieldType, obganismModifier, false); break; case "max": case "at most": case "not after": case "not above": ModifierToMaxMeta(fieldType, obganismModifier, true); break; case "below": case "before": ModifierToMaxMeta(fieldType, obganismModifier, false); break; case "between": ModifierToMinMaxMeta(fieldType, obganismModifier, false); break; case "in": ModifierToMinMaxMeta(fieldType, obganismModifier, true); break; case "enum": case "one of": case "amongst": ModifierToAllowedValuesMeta(fieldType, obganismModifier); break; case "not one of": case "not amongst": ModifierToForbiddenValuesMeta(fieldType, obganismModifier); break; case "allow empty": fieldType.Meta[NapBuiltInMeta.AllowEmpty] = true; break; case "not empty": fieldType.Meta[NapBuiltInMeta.AllowEmpty] = false; break; case "multiline": fieldType.Meta[NapBuiltInMeta.AllowMultiline] = true; break; case "not multiline": fieldType.Meta[NapBuiltInMeta.AllowMultiline] = false; break; case "pattern": ModifierToPatternMeta(fieldType, obganismModifier); break; case "same as": ModifierToSameAsMeta(fieldType, obganismModifier); break; case "not same as": ModifierToNotSameAsMeta(fieldType, obganismModifier); break; case "self": fieldType.Meta[NapBuiltInMeta.SelfReference] = SelfReference.Enforce; break; case "not self": fieldType.Meta[NapBuiltInMeta.SelfReference] = SelfReference.Forbid; break; case "optional": fieldType.Meta[NapBuiltInMeta.IsOptional] = true; break; case "not optional": fieldType.Meta[NapBuiltInMeta.IsOptional] = false; break; case "default": ModifierToDefaultMeta(fieldType, obganismModifier); break; case "allow duplicates": fieldType.Meta[NapBuiltInMeta.AllowDuplicates] = true; break; case "no duplicates": fieldType.Meta[NapBuiltInMeta.AllowDuplicates] = false; break; // Collection Generic Meta // ---- case "all min": case "all at least": case "not any below": case "not any before": ModifierToMinMeta(GetMetaTargetGeneric(fieldType), obganismModifier, true); break; case "all above": case "all after": ModifierToMinMeta(GetMetaTargetGeneric(fieldType), obganismModifier, false); break; case "all max": case "all at most": case "not any after": case "not any above": ModifierToMaxMeta(GetMetaTargetGeneric(fieldType), obganismModifier, true); break; case "all below": case "all before": ModifierToMaxMeta(GetMetaTargetGeneric(fieldType), obganismModifier, false); break; case "all between": ModifierToMinMaxMeta(GetMetaTargetGeneric(fieldType), obganismModifier, false); break; case "all in": ModifierToMinMaxMeta(GetMetaTargetGeneric(fieldType), obganismModifier, true); break; case "all one of": case "all amongst": ModifierToAllowedValuesMeta(GetMetaTargetGeneric(fieldType), obganismModifier); break; case "not any one of": case "not any amongst": ModifierToForbiddenValuesMeta(GetMetaTargetGeneric(fieldType), obganismModifier); break; case "any empty": GetMetaTargetGeneric(fieldType).Meta[NapBuiltInMeta.AllowEmpty] = true; break; case "not any empty": GetMetaTargetGeneric(fieldType).Meta[NapBuiltInMeta.AllowEmpty] = false; break; case "all multiline": GetMetaTargetGeneric(fieldType).Meta[NapBuiltInMeta.AllowMultiline] = true; break; case "not any multiline": GetMetaTargetGeneric(fieldType).Meta[NapBuiltInMeta.AllowMultiline] = false; break; case "all pattern": ModifierToPatternMeta(GetMetaTargetGeneric(fieldType), obganismModifier); break; case "all same as": ModifierToSameAsMeta(GetMetaTargetGeneric(fieldType), obganismModifier); break; case "not any same as": ModifierToNotSameAsMeta(GetMetaTargetGeneric(fieldType), obganismModifier); break; case "all self": GetMetaTargetGeneric(fieldType).Meta[NapBuiltInMeta.SelfReference] = SelfReference.Enforce; break; case "not any self": GetMetaTargetGeneric(fieldType).Meta[NapBuiltInMeta.SelfReference] = SelfReference.Forbid; break; case "all optional": GetMetaTargetGeneric(fieldType).Meta[NapBuiltInMeta.IsOptional] = true; break; case "not any optional": GetMetaTargetGeneric(fieldType).Meta[NapBuiltInMeta.IsOptional] = false; break; // Custom Meta // ---- //default: ModifierToCustomMeta(fieldType, obganismModifier); break; } }