/// <summary> /// Returns true if the two types are perceivably different in json. /// For example, Int64 and Int16 generally look the same. /// Double and Int32 generally look different. /// Guid and String generally look different. And so on. /// </summary> /// <param name="type"></param> /// <returns></returns> internal bool JsonLooksDifferentFrom(ParameterDataType type) { if (type == null) { return(true); } if (this.IsCollection) { if (type.IsCollection) { return(new ParameterDataType(this.CollectionResourceType).JsonLooksDifferentFrom(new ParameterDataType(type.CollectionResourceType))); } else { return(true); } } else if (type.IsCollection) { return(true); } if (this.Type == type.Type) { return(false); } switch (this.Type) { case SimpleDataType.Boolean: return(type.Type != SimpleDataType.Boolean); case SimpleDataType.Byte: case SimpleDataType.Int16: case SimpleDataType.Int32: case SimpleDataType.Int64: return (type.Type != SimpleDataType.Byte && type.Type != SimpleDataType.Int16 && type.Type != SimpleDataType.Int32 && type.Type != SimpleDataType.Int64); case SimpleDataType.Double: case SimpleDataType.Float: case SimpleDataType.Single: return (type.Type != SimpleDataType.Double && type.Type != SimpleDataType.Float && type.Type != SimpleDataType.Single); default: // default to assuming the types look different return(true); } }
public ParameterDataType(ParameterDataType existingType, IEnumerable <ParameterDefinition> customMembers) { this.Type = existingType.Type; this.CollectionResourceType = existingType.CollectionResourceType; this.CustomTypeName = existingType.CustomTypeName; this.IsEnum = existingType.IsEnum; if (null != customMembers) { this.CustomMembers = customMembers.ToList(); } }
public static ParameterDataType ChooseBest(ParameterDataType a, ParameterDataType b) { if (b.IsLessSpecificThan(a)) { return(a); } else { return(b); } }
public override bool Equals(object obj) { if (obj is ParameterDataType) { ParameterDataType other = (ParameterDataType)obj; return(this.Type == other.Type && this.CollectionResourceType == other.CollectionResourceType && this.CustomTypeName == other.CustomTypeName); } return(false); }
/// <summary> /// Returns a new instance that represents a collection of a given type of object. /// </summary> /// <param name="type"></param> /// <returns></returns> public static ParameterDataType CollectionOfType(ParameterDataType type) { return(new ParameterDataType { Type = SimpleDataType.Collection, CustomTypeName = type.CustomTypeName, CollectionResourceType = type.Type, CollectionDimensions = type.IsCollection ? 2 : 1, IsEnum = type.IsEnum, }); }
static ParameterDataType() { String = new ParameterDataType(SimpleDataType.String); GenericObject = new ParameterDataType(SimpleDataType.Object); GenericCollection = new ParameterDataType(SimpleDataType.Object, true); Boolean = new ParameterDataType(SimpleDataType.Boolean); Double = new ParameterDataType(SimpleDataType.Double); Float = new ParameterDataType(SimpleDataType.Float); Guid = new ParameterDataType(SimpleDataType.Guid); Int64 = new ParameterDataType(SimpleDataType.Int64); Int32 = new ParameterDataType(SimpleDataType.Int32); DateTimeOffset = new ParameterDataType(SimpleDataType.DateTimeOffset); }
/// <summary> /// Returns true if the current ParameterDataType instance is less /// qualified than the type provided in the arguments. /// {complex type} > {simple type} > {string} > {object} /// </summary> /// <param name="type"></param> /// <returns></returns> internal bool IsLessSpecificThan(ParameterDataType type) { /* * For JSON, we basically have the following hierarchy of data types: * * string * -> GUID * -> DateTimeOffset * -> TimeSpan * * int64 * ->int32 * ->int16 * ->boolean * * float * -> double * * object * -> complex type * * stream * * We should never allow something from one tree to be considered less specific than something in a different tree. */ if (type == null) { return(false); } if (this.IsCollection) { if (type.IsCollection) { return(new ParameterDataType(this.CollectionResourceType).IsLessSpecificThan(new ParameterDataType(type.CollectionResourceType))); } else { return(false); } } if (this.IsCollection != type.IsCollection) { return(false); } if (this.Type == SimpleDataType.String && (type.Type == SimpleDataType.Guid || type.Type == SimpleDataType.DateTimeOffset || type.Type == SimpleDataType.TimeSpan)) { return(true); } else if (this.Type == SimpleDataType.Int64 && (type.Type == SimpleDataType.Int32 || type.Type == SimpleDataType.Int16 || type.Type == SimpleDataType.Boolean)) { return(true); } else if (this.Type == SimpleDataType.Double && (type.Type == SimpleDataType.Float)) { return(true); } else if (this.Type == SimpleDataType.Object && type.Type == SimpleDataType.Object && this.CustomTypeName.IEquals("Edm.Object")) { return(true); } return(false); }
/// <summary> /// Helper method that converts a string value into a ParameterDataType instance /// </summary> /// <param name="value"></param> /// <param name="addErrorAction"></param> /// <returns></returns> public static ParameterDataType ParseParameterDataType(this string value, bool isCollection = false, Action <ValidationError> addErrorAction = null, ParameterDataType defaultValue = null) { const string collectionPrefix = "collection("; const string collectionOfPrefix = "collection of"; const string collectionSuffix = " collection"; if (value == null) { return(null); } if (value.StartsWith(collectionPrefix, StringComparison.OrdinalIgnoreCase)) { isCollection = true; value = value.Substring(collectionPrefix.Length).TrimEnd(')'); } else if (value.StartsWith(collectionOfPrefix, StringComparison.OrdinalIgnoreCase)) { isCollection = true; value = value.Substring(collectionOfPrefix.Length).TrimEnd(')'); } else if (value.EndsWith(collectionSuffix, StringComparison.OrdinalIgnoreCase)) { isCollection = true; value = value.Replace(collectionSuffix, string.Empty); } // Value could have markdown formatting in it, so we do some basic work to try and remove that if it exists if (value.IndexOf('[') != -1) { value = value.TextBetweenCharacters('[', ']'); } SimpleDataType simpleType = ParseSimpleTypeString(value.ToLowerInvariant()); if (simpleType != SimpleDataType.None) { return(new ParameterDataType(simpleType, isCollection)); } // some inferences for common descriptions ParameterDataType inferredType = null; if (value.IContains("etag")) { inferredType = ParameterDataType.String; } else if (value.IContains("timestamp")) { inferredType = ParameterDataType.DateTimeOffset; } else if (value.IContains("string")) { inferredType = ParameterDataType.String; } bool isEnum = false; if (value.IContains(" enum")) { isEnum = true; value = value.IReplace(" enum", string.Empty).Trim(); } if (inferredType != null) { if (isCollection) { inferredType = ParameterDataType.CollectionOfType(inferredType); } return(inferredType); } // if there aren't any spaces or special characters, assume we parsed the name of a type correctly. if (value.IndexOfAny(new[] { ' ', '/' }) == -1) { SchemaConfig config = DocSet.SchemaConfig; if (!(config?.NotLowerCamel?.Contains(value)).GetValueOrDefault()) { value = char.ToLowerInvariant(value[0]) + value.Substring(1); } if (value.IndexOf('.') == -1 && !string.IsNullOrEmpty(config?.DefaultNamespace)) { value = config.DefaultNamespace + "." + value; } return(new ParameterDataType(value, isCollection, isEnum)); } if (defaultValue != null) { return(defaultValue); } if (null != addErrorAction) { addErrorAction(new ValidationWarning(ValidationErrorCode.TypeConversionFailure, "Couldn't convert '{0}' into understood data type. Assuming Object type.", value)); } return(new ParameterDataType(value, isCollection)); }