public DotnetProperty(PropertyInfo property, Avro.Schema.Type schemaTag, IAvroFieldConverter converter, ClassCache cache) { _property = property; Converter = converter; if (!IsPropertyCompatible(schemaTag)) { if (Converter == null) { var c = cache.GetDefaultConverter(schemaTag, _property.PropertyType); if (c != null) { Converter = c; return; } } throw new AvroException($"Property {property.Name} in object {property.DeclaringType} isn't compatible with Avro schema type {schemaTag}"); } }
public DotnetProperty(PropertyInfo property, Avro.Schema.Type schemaTag, ClassCache cache) : this(property, schemaTag, null, cache) { }
private bool IsPropertyCompatible(Avro.Schema.Type schemaTag) { Type propType; if (Converter == null) { propType = _property.PropertyType; } else { propType = Converter.GetAvroType(); } switch (schemaTag) { case Avro.Schema.Type.Null: return((Nullable.GetUnderlyingType(propType) != null) || (!propType.IsValueType)); case Avro.Schema.Type.Boolean: return(propType == typeof(bool)); case Avro.Schema.Type.Int: return(propType == typeof(int)); case Avro.Schema.Type.Long: return(propType == typeof(long)); case Avro.Schema.Type.Float: return(propType == typeof(float)); case Avro.Schema.Type.Double: return(propType == typeof(double)); case Avro.Schema.Type.Bytes: return(propType == typeof(byte[])); case Avro.Schema.Type.String: return(typeof(string).IsAssignableFrom(propType)); case Avro.Schema.Type.Record: //TODO: this probably should work for struct too return(propType.IsClass); case Avro.Schema.Type.Enumeration: return(propType.IsEnum); case Avro.Schema.Type.Array: return(typeof(IEnumerable).IsAssignableFrom(propType)); case Avro.Schema.Type.Map: return(typeof(IDictionary).IsAssignableFrom(propType)); case Avro.Schema.Type.Union: return(true); case Avro.Schema.Type.Fixed: return(propType == typeof(byte[])); case Avro.Schema.Type.Error: return(propType.IsClass); } return(false); }
/// <summary> /// Find a default converter /// </summary> /// <param name="tag"></param> /// <param name="propType"></param> /// <returns>The first matching converter - null if there isnt one</returns> public IAvroFieldConverter GetDefaultConverter(Avro.Schema.Type tag, Type propType) { Type avroType; switch (tag) { case Avro.Schema.Type.Null: return(null); case Avro.Schema.Type.Boolean: avroType = typeof(bool); break; case Avro.Schema.Type.Int: avroType = typeof(int); break; case Avro.Schema.Type.Long: avroType = typeof(long); break; case Avro.Schema.Type.Float: avroType = typeof(float); break; case Avro.Schema.Type.Double: avroType = typeof(double); break; case Avro.Schema.Type.Bytes: avroType = typeof(byte[]); break; case Avro.Schema.Type.String: avroType = typeof(string); break; case Avro.Schema.Type.Record: return(null); case Avro.Schema.Type.Enumeration: return(null); case Avro.Schema.Type.Array: return(null); case Avro.Schema.Type.Map: return(null); case Avro.Schema.Type.Union: return(null); case Avro.Schema.Type.Fixed: avroType = typeof(byte[]); break; case Avro.Schema.Type.Error: return(null); default: return(null); } foreach (var c in _defaultConverters) { if (c.GetAvroType() == avroType && c.GetPropertyType() == propType) { return(c); } } return(null); }