using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text.RegularExpressions; using Luticate2.Auth.Utils.Business.Utils; using Luticate2.Auth.Utils.Dbo.Fields; namespace Luticate2.Auth.Utils.Business.Fields { public static class LuFieldsExtensions { public static bool IsIncluded(this IEnumerable fields, IEnumerable parts, bool ignoreCase = true) { return fields.Any(x => x.IsIncluded(parts, ignoreCase)); } public static bool IsIncluded(this IEnumerable fields, string path, bool ignoreCase = true) { return fields.Any(x => x.IsIncluded(path, ignoreCase)); } public static bool IsIncluded(this IEnumerable fields, LuFieldDbo path, bool ignoreCase = true) { return fields.Any(x => x.IsIncluded(path, ignoreCase)); } public static bool IsIncluded(this IEnumerable fields, Expression> property, bool ignoreCase = true) { return fields.Any(x => x.IsIncluded(property, ignoreCase)); } public static bool IsIncluded(this LuFieldDbo field, IEnumerable parts, bool ignoreCase = true) { var list = parts.ToList(); var stringComparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; for (var index = 0; index < list.Count && index < field.Parts.Count; index++) { if (!string.Equals(list[index], field.Parts[index], stringComparison) && field.Parts[index] != "*") { return false; } // If the last part of the given value is reached and the field has more parts than the given value, // there is no match, eg. the field value is foo/bar and the given value is foo. If the field parts and // the given value parts have equal lengths, there is a match, eg. the field value is foo/bar and the // given value is foo/bar. if (index == list.Count - 1) { return list.Count <= field.Parts.Count; } } return true; } public static bool IsIncluded(this LuFieldDbo field, string path, bool ignoreCase = true) { return field.IsIncluded(LuFieldDbo.Make(path), ignoreCase); } public static bool IsIncluded(this LuFieldDbo field, LuFieldDbo path, bool ignoreCase = true) { return field.IsIncluded(path.Parts, ignoreCase); } public static bool IsIncluded(this LuFieldDbo field, Expression> property, bool ignoreCase = true) { var memberInfo = LuExpressionUtils.GetMembersFromExpression(property); var parts = memberInfo.Select(x => x.Name).ToList(); return field.IsIncluded(parts, ignoreCase); } public static bool StartsWith(this LuFieldDbo field, IEnumerable subParts, bool ignoreCase = true) { var comparer = ignoreCase ? StringComparer.CurrentCultureIgnoreCase : StringComparer.CurrentCulture; using (IEnumerator enumerator = field.Parts.GetEnumerator()) { foreach (string source in subParts) { if (!enumerator.MoveNext() || comparer.Compare(enumerator.Current, source) != 0) return false; } } return true; } public static bool StartsWith(this LuFieldDbo field, string subparts, bool ignoreCase = true) { return field.StartsWith(LuFieldDbo.Make(subparts), ignoreCase); } public static bool StartsWith(this LuFieldDbo field, LuFieldDbo path, bool ignoreCase = true) { return field.StartsWith(path.Parts, ignoreCase); } public static bool StartsWith(this LuFieldDbo field, Expression> property, bool ignoreCase = true) { var memberInfo = LuExpressionUtils.GetMembersFromExpression(property); var memberInfoString = memberInfo.Select(x => x.Name).ToList(); return field.StartsWith(memberInfoString, ignoreCase); } public static bool Is(this LuFieldDbo field, IEnumerable parts, bool ignoreCase = true) { var comparer = ignoreCase ? StringComparer.CurrentCultureIgnoreCase : StringComparer.CurrentCulture; return field.Parts.SequenceEqual(parts, comparer); } public static bool Is(this LuFieldDbo field, string parts, bool ignoreCase = true) { return field.Is(LuFieldDbo.Make(parts), ignoreCase); } public static bool Is(this LuFieldDbo field, LuFieldDbo path, bool ignoreCase = true) { return field.Is(path.Parts, ignoreCase); } public static bool Is(this LuFieldDbo field, Expression> property, bool ignoreCase = true) { var memberInfo = LuExpressionUtils.GetMembersFromExpression(property); var memberInfoString = memberInfo.Select(x => x.Name).ToList(); return field.Is(memberInfoString, ignoreCase); } public static bool IsRoot(this LuFieldDbo field) { return !field.Parts.Any(); } public static LuFieldDbo Pop(this LuFieldDbo field) { field.Parts = field.Parts.Where((s, i) => i != 0).ToList(); return field; } public static LuFieldDbo Popped(this LuFieldDbo field) { var newField = LuFieldDbo.Make(field).Pop(); return newField; } public static LuFieldDbo Add(this LuFieldDbo field, IEnumerable parts) { foreach (var property in parts) { if (!string.IsNullOrEmpty(property)) { field.Parts.Add(property); } } return field; } public static LuFieldDbo Add(this LuFieldDbo field, LuFieldDbo path) { return field.Add(path.Parts); } public static LuFieldDbo Add(this LuFieldDbo field, string path) { return field.Add(Regex.Split(path, "[\\./]")); } public static LuFieldDbo Add(this LuFieldDbo field, Expression> property) { var memberInfo = LuExpressionUtils.GetMembersFromExpression(property); if (memberInfo == null) { throw new ArgumentException("Invalid property", nameof(property)); } return field.Add(memberInfo.Select(x => x.Name)); } } }