<commit_before>﻿namespace Dapper.FluentColumnMapping
{
    using System;
    using System.Linq.Expressions;
    using System.Reflection;

    /// <summary>Class containing extension methods for registering column mappings.</summary>
    /// <remarks>
    ///     <para>
    ///         The extension methods herein sometimes return/accept interfaces and sometimes concrete types.
    ///     </para>
    ///     <para>
    ///         This is intentional so as to have IntelliSense only display the appropriate extension methods when
    ///         chaining calls (i.e. mapping fluently).
    ///     </para>
    ///     <para>
    ///         For example, you shouldn't be able to directly chain multiple calls to
    ///         <see cref="ExtensionMethods.ToColumn{T}(PropertyMapping{T}, string)"/>.
    ///         You should only be able to call that method after having called
    ///         <see cref="ExtensionMethods.MapProperty{T}(IMappedType{T}, Expression{Func{T, string}})"/> or
    ///         <see cref="ExtensionMethods.MapProperty{T}(IColumnMapping{T}, Expression{Func{T, string}})"/>.
    ///     </para>
    /// </remarks>
    public static class ExtensionMethods
    {
        /// <summary>Registers a new column mapping for a specific <see cref="Type"/>.</summary>
        /// <typeparam name="T">The <see cref="Type"/> associated with the column mapping.</typeparam>
        /// <param name="mappings">The <see cref="ColumnMappingCollection"/> to register the mapping with.</param>
        /// <returns>
        ///     An instance of <see cref="MappedType{T}"/> that has been
        ///     registered with the <see cref="ColumnMappingCollection"/>
        ///     provided in the <paramref name="mappings"/> parameter.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if the <paramref name="mappings"/> parameter is <c>null</c>.
        /// </exception>
        public static MappedType<T> RegisterType<T>(this ColumnMappingCollection mappings)
        {
            if (mappings == null)
                throw new ArgumentNullException(nameof(mappings));

            var mappedType = new MappedType<T>();
            mappings.Mappings.Add(typeof(T), mappedType);

            return mappedType;
        }

        /// <summary>
        ///     Gets a <see cref="bool"/> value indicating whether a given <see cref="Type"/>
        ///     has been registered with a <see cref="ColumnMappingCollection"/>.
        /// </summary>
        /// <typeparam name="T">The <see cref="Type"/> to check for.</typeparam>
        /// <param name="mappings">The instance of <see cref="ColumnMappingCollection"/> to check.</param>
        /// <returns>
        ///     A <see cref="bool"/> value indicating whether a given <see cref="Type"/>
        ///     has been registered with a <see cref="ColumnMappingCollection"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if the <paramref name="mappings"/> parameter is <c>null</c>.
        /// </exception>
        public static bool TypeHasBeenMapped<T>(this ColumnMappingCollection mappings)
        {
            if (mappings == null)
                throw new ArgumentNullException(nameof(mappings));

            return mappings.Mappings.ContainsKey(typeof(T));
        }

        /// <summary>
        ///     Gets the <see cref="MappedType{T}"/> for a specific <see cref="Type"/>
        ///     that has a mapping registered with a <see cref="ColumnMappingCollection"/>.
        /// </summary>
        /// <typeparam name="T">
        ///     The registered <see cref="Type"/> to get the column mappings for.
        /// </typeparam>
        /// <param name="mappings">
        ///     The instance of <see cref="ColumnMappingCollection"/> containing the registered instance of
        ///     <see cref="MappedType{T}"/> associated with the <see cref="Type"/> specified for <typeparamref name="T"/>.
        /// </param>
        /// <returns>
        ///     If the <see cref="Type"/> specified for <typeparamref name="T"/> has
        ///     been registered with the <see cref="ColumnMappingCollection"/>, then
        ///     the registered <see cref="MappedType{T}"/>; otherwise, <c>null</c>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if the <paramref name="mappings"/> parameter is <c>null</c>.
        /// </exception>
        public static MappedType<T> GetTypeMapping<T>(this ColumnMappingCollection mappings)
        {
            if (mappings == null)
                throw new ArgumentNullException(nameof(mappings));

            return mappings.Mappings[typeof(T)] as MappedType<T>;
        }

        /// <summary>Adds a property/field to the mapping.</summary>
        /// <typeparam name="T">The <see cref="Type"/> associated with the column mapping.</typeparam>
        /// <param name="columnMapping">
        ///     An instance of <see cref="IColumnMapping{T}"/> that has been added to the current mapping.
        /// </param>
        /// <param name="propertyName">
        ///     An <see cref="Expression{T}"/> selecting the property/field to add to the mapping.
        /// </param>
        /// <returns><commit_msg>Adding extension method with option to throw exception if Type not registered<commit_after>﻿namespace Dapper.FluentColumnMapping
{
    using System;
    using System.Linq.Expressions;
    using System.Reflection;

    /// <summary>Class containing extension methods for registering column mappings.</summary>
    /// <remarks>
    ///     <para>
    ///         The extension methods herein sometimes return/accept interfaces and sometimes concrete types.
    ///     </para>
    ///     <para>
    ///         This is intentional so as to have IntelliSense only display the appropriate extension methods when
    ///         chaining calls (i.e. mapping fluently).
    ///     </para>
    ///     <para>
    ///         For example, you shouldn't be able to directly chain multiple calls to
    ///         <see cref="ExtensionMethods.ToColumn{T}(PropertyMapping{T}, string)"/>.
    ///         You should only be able to call that method after having called
    ///         <see cref="ExtensionMethods.MapProperty{T}(IMappedType{T}, Expression{Func{T, string}})"/> or
    ///         <see cref="ExtensionMethods.MapProperty{T}(IColumnMapping{T}, Expression{Func{T, string}})"/>.
    ///     </para>
    /// </remarks>
    public static class ExtensionMethods
    {
        /// <summary>Registers a new column mapping for a specific <see cref="Type"/>.</summary>
        /// <typeparam name="T">The <see cref="Type"/> associated with the column mapping.</typeparam>
        /// <param name="mappings">The <see cref="ColumnMappingCollection"/> to register the mapping with.</param>
        /// <returns>
        ///     An instance of <see cref="MappedType{T}"/> that has been
        ///     registered with the <see cref="ColumnMappingCollection"/>
        ///     provided in the <paramref name="mappings"/> parameter.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if the <paramref name="mappings"/> parameter is <c>null</c>.
        /// </exception>
        public static MappedType<T> RegisterType<T>(this ColumnMappingCollection mappings)
        {
            if (mappings == null)
                throw new ArgumentNullException(nameof(mappings));

            var mappedType = new MappedType<T>();
            mappings.Mappings.Add(typeof(T), mappedType);

            return mappedType;
        }

        /// <summary>
        ///     Gets a <see cref="bool"/> value indicating whether a given <see cref="Type"/>
        ///     has been registered with a <see cref="ColumnMappingCollection"/>.
        /// </summary>
        /// <typeparam name="T">The <see cref="Type"/> to check for.</typeparam>
        /// <param name="mappings">The instance of <see cref="ColumnMappingCollection"/> to check.</param>
        /// <returns>
        ///     A <see cref="bool"/> value indicating whether a given <see cref="Type"/>
        ///     has been registered with a <see cref="ColumnMappingCollection"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if the <paramref name="mappings"/> parameter is <c>null</c>.
        /// </exception>
        public static bool TypeHasBeenMapped<T>(this ColumnMappingCollection mappings)
        {
            if (mappings == null)
                throw new ArgumentNullException(nameof(mappings));

            return mappings.Mappings.ContainsKey(typeof(T));
        }

        /// <summary>
        ///     Gets the <see cref="MappedType{T}"/> for a specific <see cref="Type"/>
        ///     that has a mapping registered with a <see cref="ColumnMappingCollection"/>.
        /// </summary>
        /// <typeparam name="T">
        ///     The registered <see cref="Type"/> to get the column mappings for.
        /// </typeparam>
        /// <param name="mappings">
        ///     The instance of <see cref="ColumnMappingCollection"/> containing the registered instance of
        ///     <see cref="MappedType{T}"/> associated with the <see cref="Type"/> specified for <typeparamref name="T"/>.
        /// </param>
        /// <returns>
        ///     If the <see cref="Type"/> specified for <typeparamref name="T"/> has
        ///     been registered with the <see cref="ColumnMappingCollection"/>, then
        ///     the registered <see cref="MappedType{T}"/>; otherwise, <c>null</c>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if the <paramref name="mappings"/> parameter is <c>null</c>.
        /// </exception>
        public static MappedType<T> GetTypeMapping<T>(this ColumnMappingCollection mappings)
        {
            return GetTypeMapping<T>(mappings, false);
        }

        /// <summary>
        ///     Gets the <see cref="MappedType{T}"/> for a specific <see cref="Type"/>
        ///     that has a mapping registered with a <see cref="ColumnMappingCollection"/>.
        /// </summary>
        /// <typeparam name="T">
        ///     The registered <see cref="Type"/> to get the column mappings for.
        /// </typeparam>
        /// <param name="mappings">
        ///     The instance of <see cref="ColumnMappingCollection"/> containing the registered instance of
        ///     <see cref="MappedType{T}"/> associated with the <see cref="Type"/> specified for <typeparamref name="T"/>.
        /// </param>
        /// <param name="throwIfTypeNotMapped"></param>
        /// <returns>
        ///     The <see cref="MappedType{T}"/> that has been registered with the
        ///     <see cref="ColumnMappingCollection"/> for the <see cref="Type"/>
        ///     specified for <typeparamref name="T"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if the <paramref name="mappings"/> parameter is <c>null</c>.
        /// </exception>
        /// <exception cref="System.Collections.Generic.KeyNotFoundException">
        ///     Thrown if the <paramref name="throwIfTypeNotMapped"/> parameter is set to <c>true</c>,
        ///     and if the <see cref="Type"/> specified for <typeparamref name="T"/> has not been
        ///     registered with the <see cref="ColumnMappingCollection"/>.
        /// </exception>
        public static MappedType<T> GetTypeMapping<T>(this ColumnMappingCollection mappings, bool throwIfTypeNotMapped)
        {
            if (mappings == null)
                throw new ArgumentNullException(nameof(mappings));

            if (mappings.TypeHasBeenMapped<T>())
                return mappings.Mappings[typeof(T)] as MappedType<T>;

            if (!throwIfTypeNotMapped)
                return null;

            var message = $"The {typeof(T)} type has not been registered with the {typeof(ColumnMappingCollection).Name}.";
            throw new System.Collections.Generic.KeyNotFoundException(message);
        }

        /// <summary>Adds a property/field to the mapping.</summary>
        /// <typeparam name="T">The <see cref="Type"/> associated with the column mapping.</typeparam>
        /// <param name="columnMapping">
        ///     An instance of <see cref="IColumnMapping{T}"/> that has been added to the current mapping.
        /// </param>
        /// <param name="propertyName">
        ///     An <see cref="Expression{T}"/> selecting the property/field to add to the mapping.
        /// </param>
        /// <returns>
{'fraction_non_alphanumeric': 0.14535389482008698, 'fraction_numerical': 0.0, 'mean_word_length': 2.1193882585101136, 'pattern_counts': {'":': 0, '<': 240, '<?xml version=': 0, '>': 240, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4620960', 'n_tokens_mistral': 3227, 'n_tokens_neox': 3185, 'n_words': 979}