using System.Collections;
using System.Globalization;
namespace QWERTYkez.WordProcessor;
///
/// Множество строк, которое автоматически приводит все добавляемые элементы
/// к верхнему регистру и удаляет диакритические знаки (например, 'ё' -> 'Е').
/// Реализует ISet<string>, поэтому может использоваться там, где ожидается этот интерфейс.
///
internal class NormalizedSet : ISet
{
private readonly HashSet _inner;
///
/// Создаёт пустое нормализованное множество.
///
public NormalizedSet()
{
_inner = [];
}
///
/// Создаёт нормализованное множество, заполненное элементами из указанной коллекции.
///
/// Коллекция, элементы которой будут нормализованы и добавлены.
public NormalizedSet(IEnumerable collection)
{
_inner = [.. collection.Select(Normalize)];
}
///
/// Нормализует строку: верхний регистр и удаление диакритики.
///
private static string Normalize(string s)
{
if (string.IsNullOrEmpty(s))
return s;
var normalized = s.Normalize(NormalizationForm.FormD);
var sb = new StringBuilder();
foreach (char c in normalized)
{
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
sb.Append(c);
}
return sb.ToString().Normalize(NormalizationForm.FormC).ToUpperInvariant();
}
// ---------- Реализация ISet ----------
public bool Add(string item) => _inner.Add(Normalize(item));
void ICollection.Add(string item) => Add(item);
public void UnionWith(IEnumerable other)
{
foreach (var item in other)
Add(item);
}
public void IntersectWith(IEnumerable other)
{
var normalizedOther = new HashSet(other.Select(Normalize));
_inner.IntersectWith(normalizedOther);
}
public void ExceptWith(IEnumerable other)
{
var normalizedOther = new HashSet(other.Select(Normalize));
_inner.ExceptWith(normalizedOther);
}
public void SymmetricExceptWith(IEnumerable other)
{
var normalizedOther = new HashSet(other.Select(Normalize));
_inner.SymmetricExceptWith(normalizedOther);
}
public bool IsSubsetOf(IEnumerable other)
{
var normalizedOther = new HashSet(other.Select(Normalize));
return _inner.IsSubsetOf(normalizedOther);
}
public bool IsSupersetOf(IEnumerable other)
{
var normalizedOther = new HashSet(other.Select(Normalize));
return _inner.IsSupersetOf(normalizedOther);
}
public bool IsProperSupersetOf(IEnumerable other)
{
var normalizedOther = new HashSet(other.Select(Normalize));
return _inner.IsProperSupersetOf(normalizedOther);
}
public bool IsProperSubsetOf(IEnumerable other)
{
var normalizedOther = new HashSet(other.Select(Normalize));
return _inner.IsProperSubsetOf(normalizedOther);
}
public bool Overlaps(IEnumerable other)
{
var normalizedOther = new HashSet(other.Select(Normalize));
return _inner.Overlaps(normalizedOther);
}
public bool SetEquals(IEnumerable other)
{
var normalizedOther = new HashSet(other.Select(Normalize));
return _inner.SetEquals(normalizedOther);
}
// ---------- Реализация ICollection ----------
public int Count => _inner.Count;
public bool IsReadOnly => false;
public void Clear() => _inner.Clear();
public bool Contains(string item) => _inner.Contains(Normalize(item));
public void CopyTo(string[] array, int arrayIndex) => _inner.CopyTo(array, arrayIndex);
public bool Remove(string item) => _inner.Remove(Normalize(item));
// ---------- Реализация IEnumerable и IEnumerable ----------
public IEnumerator GetEnumerator() => _inner.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}