private ManualTypeDescriberBuilder WithDeserializeMember(TypeInfo?forType, Setter?setter, string?name, Parser?parser, MemberRequired required, Reset?reset) { if (forType == null) { Throw.ArgumentNullException(nameof(forType)); } if (setter == null) { Throw.ArgumentNullException(nameof(setter)); } if (name == null) { Throw.ArgumentNullException(nameof(name)); } if (parser == null) { Throw.ArgumentNullException(nameof(parser)); } var toAdd = DeserializableMember.Create(forType, name, setter, parser, required, reset); if (!Deserializers.TryGetValue(forType, out var d)) { Deserializers[forType] = d = ImmutableArray.CreateBuilder <DeserializableMember>(); } d.Add(toAdd); return(this); }
/// <summary> /// Enumerate all columns to deserialize. /// </summary> public virtual IEnumerable <DeserializableMember> EnumerateMembersToDeserialize(TypeInfo forType) { var buffer = new List <(DeserializableMember Member, int?Position)>(); foreach (var p in forType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance)) { if (!ShouldDeserialize(forType, p)) { continue; } var name = GetDeserializationName(forType, p); var setter = GetSetter(forType, p); var parser = GetParser(forType, p); var order = GetPosition(forType, p); var isRequired = GetIsRequired(forType, p); var reset = GetReset(forType, p); buffer.Add((DeserializableMember.Create(forType, name, setter, parser, isRequired, reset), order)); } foreach (var f in forType.GetFields()) { if (!ShouldDeserialize(forType, f)) { continue; } var name = GetDeserializationName(forType, f); var parser = GetParser(forType, f); var order = GetPosition(forType, f); var isRequired = GetIsRequired(forType, f); var reset = GetReset(forType, f); buffer.Add((DeserializableMember.Create(forType, name, f, parser, isRequired, reset), order)); } buffer.Sort(TypeDescribers.DeserializableComparer); foreach (var(member, _) in buffer) { yield return(member); } }
private static DeserializableMember Map(TypeInfo ontoType, DeserializableMember member) { MethodInfo resetOnType = null; if (member.Reset != null) { var surrogateReset = member.Reset; var surrogateResetBinding = // explicitly ignoring DeclaredOnly; shadowing is fine (surrogateReset.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic) | (surrogateReset.IsStatic ? BindingFlags.Static : BindingFlags.Instance); resetOnType = ontoType.GetMethod(surrogateReset.Name, surrogateResetBinding); if (resetOnType == null) { Throw.InvalidOperationException($"No equivalent to {resetOnType} found on {ontoType}"); } } if (member.Field != null) { var surrogateField = member.Field; var surrogateFieldBinding = // explicitly ignoring DeclaredOnly; shadowing is fine (surrogateField.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic) | (surrogateField.IsStatic ? BindingFlags.Static : BindingFlags.Instance); var fieldOnType = ontoType.GetField(surrogateField.Name, surrogateFieldBinding); if (fieldOnType == null) { Throw.InvalidOperationException($"No equivalent to {surrogateField} found on {ontoType}"); } if (fieldOnType.FieldType != surrogateField.FieldType) { Throw.InvalidOperationException($"Field {fieldOnType} type ({fieldOnType.FieldType}) does not match surrogate field {surrogateField} type ({surrogateField.FieldType})"); } return(DeserializableMember.Create(ontoType, member.Name, fieldOnType, member.Parser, member.IsRequired, resetOnType)); } var surrogateSetter = member.Setter; var surrogateSetterBinding = // explicitly ignoring DeclaredOnly; shadowing is fine (surrogateSetter.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic) | (surrogateSetter.IsStatic ? BindingFlags.Static : BindingFlags.Instance); var setterOnType = ontoType.GetMethod(surrogateSetter.Name, surrogateSetterBinding); if (setterOnType == null) { Throw.InvalidOperationException($"No equivalent to {surrogateSetter} found on {ontoType}"); } var paramsOnType = setterOnType.GetParameters(); var paramsOnSurrogate = surrogateSetter.GetParameters(); if (paramsOnType.Length != paramsOnSurrogate.Length) { Throw.InvalidOperationException($"Parameters for {setterOnType} do not match parameters for {surrogateSetter}"); } for (var i = 0; i < paramsOnType.Length; i++) { var pOnType = paramsOnType[i]; var pOnSurrogate = paramsOnSurrogate[i]; if (pOnType.ParameterType != pOnSurrogate.ParameterType) { Throw.InvalidOperationException($"Parameter #{(i + 1)} on {setterOnType} does not match same parameter on {surrogateSetter}"); } } return(DeserializableMember.Create(ontoType, member.Name, setterOnType, member.Parser, member.IsRequired, resetOnType)); }