// 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 CsvHelper.TypeConversion;
using System.Collections;
namespace CsvHelper.Configuration
{
///
/// Has mapping capabilities.
///
/// The class type.
public interface IHasMap : IBuildableClass
{
///
/// Maps a member to a CSV field.
///
/// The member to map.
/// If true, an existing map will be used if available.
/// If false, a new map is created for the same member.
/// The member mapping.
IHasMapOptions Map(Expression> expression, bool useExistingMap = true);
}
///
/// Options after a mapping call.
///
/// The class type.
/// The member type.
public interface IHasMapOptions :
IHasMap,
IHasTypeConverter,
IHasIndex,
IHasName,
IHasOptional,
IHasConvertUsing,
IHasDefault,
IHasConstant,
IHasValidate
{ }
///
/// Has type converter capabilities.
///
/// The class type.
/// The member type.
public interface IHasTypeConverter : IBuildableClass
{
///
/// Specifies the to use
/// when converting the member to and from a CSV field.
///
/// The TypeConverter to use.
IHasTypeConverterOptions TypeConverter(ITypeConverter typeConverter);
///
/// Specifies the to use
/// when converting the member to and from a CSV field.
///
/// The of the
/// to use.
IHasTypeConverterOptions TypeConverter() where TConverter : ITypeConverter;
}
///
/// Options after a type converter call.
///
/// The class type.
/// The member type.
public interface IHasTypeConverterOptions :
IHasMap,
IHasDefault,
IHasValidate
{ }
///
/// Has index capabilities.
///
/// The class type.
/// The member type.
public interface IHasIndex : IBuildableClass
{
///
/// 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.
/// The end index used when mapping to an member.
IHasIndexOptions Index(int index, int indexEnd = -1);
}
///
/// Options after an index call.
///
/// The class type.
/// The member type.
public interface IHasIndexOptions :
IHasMap,
IHasTypeConverter,
IHasName,
IHasDefault,
IHasValidate
{ }
///
/// Has optional capabilities.
///
/// The class type.
/// The member type.
public interface IHasOptional : IBuildableClass
{
///
/// Ignore the member when reading if no matching field name can be found.
///
IHasOptionalOptions Optional();
}
///
/// Options after an optional call.
///
/// The class type.
/// The member type.
public interface IHasOptionalOptions :
IHasMap,
IHasTypeConverter,
IHasName,
IHasDefault,
IHasValidate
{ }
///
/// Has name capabilities.
///
/// The class type.
/// The member type.
public interface IHasName : IBuildableClass
{
///
/// 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.
IHasNameOptions Name(params string[] names);
}
///
/// Options after a name call.
///
/// The class type.
/// The member type.
public interface IHasNameOptions :
IHasMap,
IHasTypeConverter,
IHasNameIndex,
IHasDefault,
IHasValidate
{ }
///
/// Has name index capabilities.
///
/// The class type.
/// The member type.
public interface IHasNameIndex : IBuildableClass
{
///
/// 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.
IHasNameIndexOptions NameIndex(int index);
}
///
/// Options after a name index call.
///
/// The class type.
/// The member type.
public interface IHasNameIndexOptions :
IHasMap,
IHasTypeConverter,
IHasDefault,
IHasValidate
{ }
///
/// Has convert using capabilities.
///
/// The class type.
/// The member type.
public interface IHasConvertUsing : IBuildableClass
{
///
/// Specifies an expression to be used to convert data in the
/// row to the member.
///
/// The convert expression.
IHasMap ConvertUsing(ConvertFromString convertExpression);
///
/// Specifies an expression to be used to convert the object
/// to a field.
///
/// The convert expression.
IHasMap ConvertUsing(ConvertToString convertExpression);
}
///
/// Has default capabilities.
///
/// The class type.
/// The member type.
public interface IHasDefault : IBuildableClass
{
///
/// The default value that will be used when reading when
/// the CSV field is empty.
///
/// The default value.
IHasDefaultOptions Default(TMember defaultValue);
///
/// The default value that will be used when reading when
/// the CSV field is empty. This value is not type checked
/// and will use a to convert
/// the field. This could potentially have runtime errors.
///
/// The default value.
IHasDefaultOptions Default(string defaultValue);
}
///
/// Options after a default call.
///
/// The class type.
/// The member type.
public interface IHasDefaultOptions :
IHasMap,
IHasValidate
{ }
///
/// Has constant capabilities.
///
/// The class type.
/// The member type.
public interface IHasConstant : IBuildableClass
{
///
/// 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.
IHasMap Constant(TMember value);
}
///
/// Has validate capabilities.
///
/// The class type.
/// The member type.
public interface IHasValidate : IBuildableClass
{
///
/// The validate expression that will be called on every field when reading.
/// The expression should return true if the field is valid.
/// If false is returned, a
/// will be thrown.
///
/// The validation expression.
IHasMap Validate(Validate validateExpression);
}
///
/// Has build capabilities.
///
/// The class type.
public interface IBuildableClass
{
///
/// Builds the .
///
ClassMap Build();
}
internal class ClassMapBuilder : IHasMap
{
private readonly ClassMap map;
public ClassMapBuilder()
{
map = new BuilderClassMap();
}
public IHasMapOptions Map(Expression> expression, bool useExistingMap = true)
{
return new MemberMapBuilder(map, map.Map(expression, useExistingMap));
}
public ClassMap Build()
{
return map;
}
private class BuilderClassMap : ClassMap { }
}
internal class MemberMapBuilder :
IHasMap,
IHasMapOptions,
IHasTypeConverter,
IHasTypeConverterOptions,
IHasIndex,
IHasIndexOptions,
IHasName,
IHasNameOptions,
IHasNameIndex,
IHasNameIndexOptions,
IHasOptional,
IHasOptionalOptions,
IHasConvertUsing,
IHasDefault,
IHasDefaultOptions,
IHasConstant,
IHasValidate
{
private readonly ClassMap classMap;
private readonly MemberMap memberMap;
public MemberMapBuilder(ClassMap classMap, MemberMap memberMap)
{
this.classMap = classMap;
this.memberMap = memberMap;
}
#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type
public IHasMapOptions Map(Expression> expression, bool useExistingMap = true)
{
return new MemberMapBuilder(classMap, classMap.Map(expression, useExistingMap));
}
#pragma warning restore CS0693 // Type parameter has the same name as the type parameter from outer type
public IHasMap ConvertUsing(ConvertFromString convertExpression)
{
memberMap.Convert(convertExpression);
return this;
}
public IHasMap ConvertUsing(ConvertToString convertExpression)
{
memberMap.Convert(convertExpression);
return this;
}
public IHasDefaultOptions Default(TMember defaultValue)
{
memberMap.Default(defaultValue);
return this;
}
public IHasDefaultOptions Default(string defaultValue)
{
memberMap.Default(defaultValue);
return this;
}
public IHasIndexOptions Index(int index, int indexEnd = -1)
{
memberMap.Index(index, indexEnd);
return this;
}
public IHasNameOptions Name(params string[] names)
{
memberMap.Name(names);
return this;
}
public IHasNameIndexOptions NameIndex(int index)
{
memberMap.NameIndex(index);
return this;
}
public IHasOptionalOptions Optional()
{
memberMap.Optional();
return this;
}
public IHasTypeConverterOptions TypeConverter(ITypeConverter typeConverter)
{
memberMap.TypeConverter(typeConverter);
return this;
}
public IHasTypeConverterOptions TypeConverter() where TConverter : ITypeConverter
{
memberMap.TypeConverter();
return this;
}
public IHasMap Constant(TMember value)
{
memberMap.Constant(value);
return this;
}
public IHasMap Validate(Validate validateExpression)
{
memberMap.Validate(validateExpression);
return this;
}
public ClassMap Build()
{
return classMap;
}
}
}