public static ThriftType Enum(ThriftEnumMetadata enumMetadata, bool isNullable = false) { Guard.ArgumentNotNull(enumMetadata, nameof(enumMetadata)); var tt = new ThriftType(enumMetadata); return(isNullable ? tt.CoerceTo(typeof(Nullable <>).MakeGenericType(enumMetadata.EnumType)) : tt); }
private ThriftType(ThriftType underlyingType, Type nullableType) { this.CSharpType = nullableType; this.UncoercedType = underlyingType; this.ProtocolType = underlyingType.ProtocolType; keyTypeReference = null; valueTypeReference = null; structMetadata = null; enumMetadata = underlyingType.enumMetadata; }
private ThriftType(ThriftEnumMetadata enumMetadata) { Guard.ArgumentNotNull(enumMetadata, "enumMetadata"); this.ProtocolType = ThriftProtocolType.Enum; this.CSharpType = enumMetadata.EnumType; keyTypeReference = null; valueTypeReference = null; structMetadata = null; this.enumMetadata = enumMetadata; this.UncoercedType = null; }
// This should ONLY be called from buildThriftType() private ThriftType BuildThriftTypeInternal(Type csharpType) { ThriftType manualType = null; Type rawType = csharpType; if (_manualTypes.TryGetValue(csharpType, out manualType)) { return(manualType); } if (typeof(bool).Equals(rawType)) { return(ThriftType.Bool); } if (typeof(byte).Equals(rawType)) { return(ThriftType.Byte); } if (typeof(short).Equals(rawType)) { return(ThriftType.I16); } if (typeof(int).Equals(rawType)) { return(ThriftType.I32); } if (typeof(long).Equals(rawType)) { return(ThriftType.I64); } if (typeof(double).Equals(rawType)) { return(ThriftType.Double); } if (typeof(float).Equals(rawType)) { return(ThriftType.Float); } if (typeof(String).Equals(rawType)) { return(ThriftType.String); } if (typeof(Guid).Equals(rawType)) { return(ThriftType.Guid); } if (typeof(DateTime).Equals(rawType)) { return(ThriftType.DateTime); } if (typeof(Decimal).Equals(rawType)) { return(ThriftType.Decimal); } if (typeof(byte[]).Equals(rawType)) { // byte[] is encoded as BINARY and requires a coersion return(ThriftType.Binary); } if (rawType.GetTypeInfo().IsEnum) { return(ThriftType.Enum(new ThriftEnumMetadata(rawType))); } var dicType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&& t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(IDictionary <,>))); if (dicType != null) { var argTypes = dicType.GetTypeInfo().GetGenericArguments(); Type mapKeyType = argTypes[0]; Type mapValueType = argTypes[1]; return(ThriftType.Dictionary( GetMapKeyThriftTypeReference(mapKeyType), GetMapValueThriftTypeReference(mapValueType))); } if (rawType.IsArray) { var elementType = rawType.GetTypeInfo().GetElementType(); return(ThriftType.Array(GetCollectionElementThriftTypeReference(elementType))); } var setType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&& t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(ISet <>))); if (setType != null) { Type elementType = setType.GetTypeInfo().GetGenericArguments().First(); return(ThriftType.Set(GetCollectionElementThriftTypeReference(elementType))); } var listType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&& t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(IList <>))); if (listType != null) { Type elementType = listType.GetTypeInfo().GetGenericArguments().First(); return(ThriftType.List(GetCollectionElementThriftTypeReference(elementType))); } var arrayType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&& t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(IEnumerable <>))); if (arrayType != null) { Type elementType = arrayType.GetTypeInfo().GetGenericArguments().First(); return(ThriftType.Array(GetCollectionElementThriftTypeReference(elementType))); } // The void type is used by service methods and is encoded as an empty struct if (typeof(void).IsAssignableFrom(rawType) || typeof(Task).Equals(rawType)) { return(ThriftType.Void); } if (IsStructType(rawType)) { ThriftStructMetadata structMetadata = GetThriftStructMetadata(csharpType); // Unions are covered because a union looks like a struct with a single field. return(ThriftType.Struct(structMetadata)); } if (rawType.GetTypeInfo().IsGenericType&& rawType.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(Task <>))) { Type returnType = rawType.GetTypeInfo().GetGenericArguments().First(); // TODO: check that we aren't recursing through multiple futures // TODO: find a way to restrict this to return values only return(GetThriftType(returnType)); } // coerce the type if possible TypeCoercion coercion = null; if (_coercions.TryGetValue(csharpType, out coercion)) { return(coercion.ThriftType); } if (IsNullableEnum(rawType)) { coercion = _coercions.GetOrAdd(rawType, t => { ThriftEnumMetadata m = new ThriftEnumMetadata(t.GetTypeInfo().GetGenericArguments().First()); var tt = ThriftType.Enum(m, true); return(new TypeCoercion(tt)); }); return(coercion.ThriftType); } throw new ThriftyException($"Type can not be coerced to a Thrift type: {csharpType.FullName}"); }