// 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;
}
}
}