< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.Utilities.ObjectToDictionaryConverter
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Utilities/ObjectToDictionaryConverter.cs
Tag: Kestrun/Kestrun@0d738bf294e6281b936d031e1979d928007495ff
Line coverage
98%
Covered lines: 55
Uncovered lines: 1
Coverable lines: 56
Total lines: 166
Line coverage: 98.2%
Branch coverage
85%
Covered branches: 41
Total branches: 48
Branch coverage: 85.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 12/12/2025 - 17:27:19 Line coverage: 98.2% (55/56) Branch coverage: 85.4% (41/48) Total lines: 166 Tag: Kestrun/Kestrun@826bf9dcf9db118c5de4c78a3259bce9549f0dcd 12/12/2025 - 17:27:19 Line coverage: 98.2% (55/56) Branch coverage: 85.4% (41/48) Total lines: 166 Tag: Kestrun/Kestrun@826bf9dcf9db118c5de4c78a3259bce9549f0dcd

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ToDictionary(...)100%88100%
ToDictionaryObject(...)87.5%8885.71%
FromDictionaryToString(...)90%1010100%
FromEnumerableToString(...)66.66%66100%
FromObjectPropertiesToString(...)100%22100%
GetPropertyStringValue(...)50%44100%
FromDictionaryToObject(...)83.33%66100%
FromEnumerableToObject(...)100%22100%
FromObjectPropertiesToObject(...)100%22100%
GetPropertyObjectValue(...)100%11100%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Utilities/ObjectToDictionaryConverter.cs

#LineLine coverage
 1using System.Collections;
 2using System.Reflection;
 3
 4namespace Kestrun.Utilities;
 5
 6/// <summary>
 7/// Utility for converting arbitrary .NET objects to a <see cref="Dictionary{TKey, TValue}"/> with string keys and value
 8/// Handles dictionaries, enumerables, and objects with public properties.
 9/// </summary>
 10public static class ObjectToDictionaryConverter
 11{
 12    /// <summary>
 13    /// Converts an arbitrary object to a dictionary with string keys and string values.
 14    /// </summary>
 15    /// <param name="data">The object to convert. Can be a dictionary, enumerable, or any object with public properties.
 16    /// <returns>A <see cref="Dictionary{TKey, TValue}"/> with string keys and string values.</returns>
 17    /// <remarks>
 18    /// Conversion behavior:
 19    /// - <see cref="IDictionary"/>: Converts keys and values to strings.
 20    /// - <see cref="IEnumerable"/> (excluding strings): Creates indexed keys like "item[0]", "item[1]", etc.
 21    /// - Other objects: Extracts public properties as key/value pairs.
 22    /// </remarks>
 23    public static Dictionary<string, string> ToDictionary(object? data)
 24    {
 1725        return data switch
 1726        {
 127            null => [],
 828            IDictionary dictionary => FromDictionaryToString(dictionary),
 729            IEnumerable enumerable when data is not string => FromEnumerableToString(enumerable),
 530            _ => FromObjectPropertiesToString(data)
 1731        };
 32    }
 33
 34    /// <summary>
 35    /// Converts an arbitrary object to a dictionary with string keys and object values (without stringification).
 36    /// </summary>
 37    /// <param name="data">The object to convert. Can be a dictionary, enumerable, or any object with public properties.
 38    /// <returns>A <see cref="Dictionary{TKey, TValue}"/> with string keys and object values.</returns>
 39    /// <remarks>
 40    /// Conversion behavior mirrors <see cref="ToDictionary"/>, but preserves original types instead of converting to st
 41    /// </remarks>
 42    public static Dictionary<string, object?> ToDictionaryObject(object? data)
 43    {
 444        return data switch
 445        {
 046            null => [],
 147            IDictionary dictionary => FromDictionaryToObject(dictionary),
 248            IEnumerable enumerable when data is not string => FromEnumerableToObject(enumerable),
 249            _ => FromObjectPropertiesToObject(data)
 450        };
 51    }
 52
 53    private static Dictionary<string, string> FromDictionaryToString(IDictionary source)
 54    {
 855        var dict = new Dictionary<string, string>();
 56
 5457        foreach (DictionaryEntry entry in source)
 58        {
 1959            var key = entry.Key?.ToString();
 1960            if (string.IsNullOrWhiteSpace(key))
 61            {
 62                continue;
 63            }
 64
 1965            dict[key] = entry.Value?.ToString() ?? string.Empty;
 66        }
 67
 868        return dict;
 69    }
 70
 71    private static Dictionary<string, string> FromEnumerableToString(IEnumerable source)
 72    {
 373        var dict = new Dictionary<string, string>();
 374        var index = 0;
 75
 1876        foreach (var item in source)
 77        {
 678            dict[$"item[{index}]"] = item?.ToString() ?? string.Empty;
 679            index++;
 80        }
 81
 382        return dict;
 83    }
 84
 85    private static Dictionary<string, string> FromObjectPropertiesToString(object source)
 86    {
 587        var dict = new Dictionary<string, string>();
 588        var properties = source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Ignor
 89
 3690        foreach (var prop in properties)
 91        {
 1392            dict[prop.Name] = GetPropertyStringValue(prop, source);
 93        }
 94
 595        return dict;
 96    }
 97
 98    private static string GetPropertyStringValue(PropertyInfo property, object source)
 99    {
 100        try
 101        {
 13102            return property.GetValue(source)?.ToString() ?? string.Empty;
 103        }
 2104        catch
 105        {
 2106            return string.Empty;
 107        }
 13108    }
 109
 110    private static Dictionary<string, object?> FromDictionaryToObject(IDictionary source)
 111    {
 1112        var dict = new Dictionary<string, object?>();
 113
 10114        foreach (DictionaryEntry entry in source)
 115        {
 4116            var key = entry.Key?.ToString();
 4117            if (string.IsNullOrWhiteSpace(key))
 118            {
 119                continue;
 120            }
 121
 4122            dict[key] = entry.Value;
 123        }
 124
 1125        return dict;
 126    }
 127
 128    private static Dictionary<string, object?> FromEnumerableToObject(IEnumerable source)
 129    {
 1130        var dict = new Dictionary<string, object?>();
 1131        var index = 0;
 132
 10133        foreach (var item in source)
 134        {
 4135            dict[$"item[{index}]"] = item;
 4136            index++;
 137        }
 138
 1139        return dict;
 140    }
 141
 142    private static Dictionary<string, object?> FromObjectPropertiesToObject(object source)
 143    {
 2144        var dict = new Dictionary<string, object?>();
 2145        var properties = source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Ignor
 146
 14147        foreach (var prop in properties)
 148        {
 5149            dict[prop.Name] = GetPropertyObjectValue(prop, source);
 150        }
 151
 2152        return dict;
 153    }
 154
 155    private static object? GetPropertyObjectValue(PropertyInfo property, object source)
 156    {
 157        try
 158        {
 5159            return property.GetValue(source);
 160        }
 1161        catch
 162        {
 1163            return null;
 164        }
 5165    }
 166}