// 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 CsvHelper.TypeConversion; using System; using System.Diagnostics; using System.Reflection; namespace CsvHelper.Configuration { /// /// Mapping for a constructor parameter. /// This may contain value type data, a constructor type map, /// or a reference map, depending on the type of the parameter. /// [DebuggerDisplay("Data = {Data}")] public class ParameterMap { /// /// Gets the parameter map data. /// public virtual ParameterMapData Data { get; protected set; } /// /// Type converter options. /// public virtual ParameterMapTypeConverterOption TypeConverterOption { get; protected set; } /// /// Gets or sets the map for a constructor type. /// public virtual ClassMap ConstructorTypeMap { get; set; } /// /// Gets or sets the map for a reference type. /// public virtual ParameterReferenceMap ReferenceMap { get; set; } /// /// Creates an instance of using /// the given information. /// /// The parameter being mapped. public ParameterMap(ParameterInfo parameter) { TypeConverterOption = new ParameterMapTypeConverterOption(this); Data = new ParameterMapData(parameter); } /// /// When reading, is used to get the field /// at the index of the name if there was a /// header specified. It will look for the /// first name match in the order listed. /// When writing, sets the name of the /// field in the header record. /// The first name will be used. /// /// The possible names of the CSV field. public virtual ParameterMap Name(params string[] names) { if (names == null || names.Length == 0) { throw new ArgumentNullException(nameof(names)); } Data.Names.Clear(); Data.Names.AddRange(names); Data.IsNameSet = true; return this; } /// /// When reading, is used to get the /// index of the name used when there /// are multiple names that are the same. /// /// The index of the name. public virtual ParameterMap NameIndex(int index) { Data.NameIndex = index; return this; } /// /// When reading, is used to get the field at /// the given index. When writing, the fields /// will be written in the order of the field /// indexes. /// /// The index of the CSV field. public virtual ParameterMap Index(int index) { Data.Index = index; Data.IsIndexSet = true; return this; } /// /// Ignore the parameter when reading and writing. /// public virtual ParameterMap Ignore() { Data.Ignore = true; return this; } /// /// Ignore the parameter when reading and writing. /// /// True to ignore, otherwise false. public virtual ParameterMap Ignore(bool ignore) { Data.Ignore = ignore; return this; } /// /// The default value that will be used when reading when /// the CSV field is empty. /// /// The default value. public virtual ParameterMap Default(object? defaultValue) { if (defaultValue == null && Data.Parameter.ParameterType.IsValueType) { throw new ArgumentException($"Parameter of type '{Data.Parameter.ParameterType.FullName}' can't have a default value of null."); } if (defaultValue != null && defaultValue.GetType() != Data.Parameter.ParameterType) { throw new ArgumentException($"Default of type '{defaultValue.GetType().FullName}' does not match parameter of type '{Data.Parameter.ParameterType.FullName}'."); } Data.Default = defaultValue; Data.IsDefaultSet = true; return this; } /// /// The constant value that will be used for every record when /// reading and writing. This value will always be used no matter /// what other mapping configurations are specified. /// /// The constant value. public virtual ParameterMap Constant(object? constantValue) { if (constantValue == null && Data.Parameter.ParameterType.IsValueType) { throw new ArgumentException($"Parameter of type '{Data.Parameter.ParameterType.FullName}' can't have a constant value of null."); } if (constantValue != null && constantValue.GetType() != Data.Parameter.ParameterType) { throw new ArgumentException($"Constant of type '{constantValue.GetType().FullName}' does not match parameter of type '{Data.Parameter.ParameterType.FullName}'."); } Data.Constant = constantValue; Data.IsConstantSet = true; return this; } /// /// The field is optional. /// public virtual ParameterMap Optional() { Data.IsOptional = true; return this; } /// /// Specifies the to use /// when converting the parameter to and from a CSV field. /// /// The TypeConverter to use. public virtual ParameterMap TypeConverter(ITypeConverter typeConverter) { Data.TypeConverter = typeConverter; return this; } /// /// Specifies the to use /// when converting the parameter to and from a CSV field. /// /// The of the /// to use. public virtual ParameterMap TypeConverter() where TConverter : ITypeConverter { TypeConverter(ObjectResolver.Current.Resolve()); return this; } internal int GetMaxIndex() { return ReferenceMap?.GetMaxIndex() ?? Data.Index; } } }