diff options
Diffstat (limited to 'ThirdParty/CsvHelper-master/src/CsvHelper/Configuration/ClassMap`1.cs')
-rw-r--r-- | ThirdParty/CsvHelper-master/src/CsvHelper/Configuration/ClassMap`1.cs | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/ThirdParty/CsvHelper-master/src/CsvHelper/Configuration/ClassMap`1.cs b/ThirdParty/CsvHelper-master/src/CsvHelper/Configuration/ClassMap`1.cs new file mode 100644 index 0000000..d14c317 --- /dev/null +++ b/ThirdParty/CsvHelper-master/src/CsvHelper/Configuration/ClassMap`1.cs @@ -0,0 +1,112 @@ +// Copyright 2009-2022 Josh Close +// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0. +// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0. +// https://github.com/JoshClose/CsvHelper +using System; +using System.Linq.Expressions; +using System.Reflection; + +namespace CsvHelper.Configuration +{ + /// <summary> + /// Maps class members to CSV fields. + /// </summary> + /// <typeparam name="TClass">The <see cref="System.Type"/> of class to map.</typeparam> + public abstract class ClassMap<TClass> : ClassMap + { + /// <summary> + /// Creates an instance of <see cref="ClassMap{TClass}"/>. + /// </summary> + public ClassMap() : base(typeof(TClass)) { } + + /// <summary> + /// Maps a member to a CSV field. + /// </summary> + /// <param name="expression">The member to map.</param> + /// <param name="useExistingMap">If true, an existing map will be used if available. + /// If false, a new map is created for the same member.</param> + /// <returns>The member mapping.</returns> + public virtual MemberMap<TClass, TMember> Map<TMember>(Expression<Func<TClass, TMember>> expression, bool useExistingMap = true) + { + var (classMap, member) = GetMemberMap(expression); + var memberMap = classMap.Map(typeof(TClass), member, useExistingMap); ; + + return (MemberMap<TClass, TMember>)memberMap; + } + + /// <summary> + /// Maps a member to a CSV field. + /// </summary> + /// <param name="expression">The member to map.</param> + /// <param name="useExistingMap">If true, an existing map will be used if available. + /// If false, a new map is created for the same member.</param> + /// <returns>The member mapping.</returns> + public virtual MemberMap Map<T>(Expression<Func<T, object>> expression, bool useExistingMap = true) + { + var (classMap, member) = GetMemberMap(expression); + var memberMap = classMap.Map(typeof(TClass), member, useExistingMap); + + return memberMap; + } + + /// <summary> + /// Meant for internal use only. + /// Maps a member to another class map. When this is used, accessing a property through + /// sub-property mapping later won't work. You can only use one or the other. When using + /// this, ConvertUsing will also not work. + /// </summary> + /// <typeparam name="TClassMap">The type of the class map.</typeparam> + /// <param name="expression">The expression.</param> + /// <param name="constructorArgs">Constructor arguments used to create the reference map.</param> + /// <returns>The reference mapping for the member.</returns> + public virtual MemberReferenceMap References<TClassMap>(Expression<Func<TClass, object>> expression, params object[] constructorArgs) where TClassMap : ClassMap + { + var member = ReflectionHelper.GetMember(expression); + return References(typeof(TClassMap), member, constructorArgs); + } + + private (ClassMap, MemberInfo) GetMemberMap<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression) + { + var stack = ReflectionHelper.GetMembers(expression); + if (stack.Count == 0) + { + throw new InvalidOperationException($"No members were found in expression '{expression}'."); + } + + ClassMap currentClassMap = this; + MemberInfo member; + + if (stack.Count > 1) + { + // We need to add a reference map for every sub member. + while (stack.Count > 1) + { + member = stack.Pop(); + Type mapType; + var property = member as PropertyInfo; + var field = member as FieldInfo; + if (property != null) + { + mapType = typeof(DefaultClassMap<>).MakeGenericType(property.PropertyType); + } + else if (field != null) + { + mapType = typeof(DefaultClassMap<>).MakeGenericType(field.FieldType); + } + else + { + throw new InvalidOperationException("The given expression was not a property or a field."); + } + + var referenceMap = currentClassMap.References(mapType, member); + currentClassMap = referenceMap.Data.Mapping; + } + } + + // Add the member map to the last reference map. + member = stack.Pop(); + + return (currentClassMap, member); + } + } +} |