using System.Collections;
using System.Text.Json;
namespace DeepDrftContent.FileDatabase.Utils;
///
/// A map implementation that uses structural equality for keys by serializing them to JSON.
/// This provides the same behavior as the TypeScript StructuralMap.
///
/// The key type
/// The value type
public class StructuralMap : IEnumerable>
{
private readonly Dictionary> _innerMap = new();
///
/// Converts a key to its string representation for structural comparison
///
private string GetKeyString(TKey key)
{
return key switch
{
null => "null",
string s => s,
int or long or float or double or decimal => key.ToString()!,
_ => JsonSerializer.Serialize(key)
};
}
///
/// Sets a key-value pair in the map
///
public StructuralMap Set(TKey key, TValue value)
{
var keyString = GetKeyString(key);
_innerMap[keyString] = new KeyValuePair(key, value);
return this;
}
///
/// Gets a value by key, or default if not found
///
public TValue? Get(TKey key)
{
var keyString = GetKeyString(key);
return _innerMap.TryGetValue(keyString, out var pair) ? pair.Value : default;
}
///
/// Checks if the map contains the specified key
///
public bool Has(TKey key)
{
var keyString = GetKeyString(key);
return _innerMap.ContainsKey(keyString);
}
///
/// Removes a key-value pair from the map
///
public bool Delete(TKey key)
{
var keyString = GetKeyString(key);
return _innerMap.Remove(keyString);
}
///
/// Clears all entries from the map
///
public void Clear() => _innerMap.Clear();
///
/// Gets the number of entries in the map
///
public int Size => _innerMap.Count;
///
/// Enumerates all key-value pairs
///
public IEnumerator> GetEnumerator()
{
return _innerMap.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
///
/// Gets all keys in the map
///
public IEnumerable Keys => _innerMap.Values.Select(pair => pair.Key);
///
/// Gets all values in the map
///
public IEnumerable Values => _innerMap.Values.Select(pair => pair.Value);
///
/// Executes a callback for each key-value pair
///
public void ForEach(Action> callback)
{
foreach (var (key, value) in this)
{
callback(value, key, this);
}
}
}