PropertyValidator.cs 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using PixiEditor.Numerics;
  2. namespace PixiEditor.ChangeableDocument.Changeables.Graph;
  3. public delegate (bool validationResult, object? closestValidValue) ValidateProperty(object? value);
  4. public class PropertyValidator
  5. {
  6. public List<ValidateProperty> Rules { get; } = new();
  7. public PropertyValidator Min(VecI min)
  8. {
  9. return Min(min, v => new VecI(Math.Max(v.X, min.X), Math.Max(v.Y, min.Y)));
  10. }
  11. public PropertyValidator Min(VecD min)
  12. {
  13. return Min(min, v => new VecD(Math.Max(v.X, min.X), Math.Max(v.Y, min.Y)));
  14. }
  15. public PropertyValidator Min<T>(T min, Func<T, T>? adjust = null) where T : IComparable<T>
  16. {
  17. Rules.Add((value) =>
  18. {
  19. if (value is T val)
  20. {
  21. bool isValid = val.CompareTo(min) >= 0;
  22. return (isValid, isValid ? val : GetReturnValue(val, min, adjust));
  23. }
  24. return (false, GetReturnValue(min, min, adjust));
  25. });
  26. return this;
  27. }
  28. private object? GetReturnValue<T>(T original, T min, Func<T, T>? fallback) where T : IComparable<T>
  29. {
  30. if (fallback != null)
  31. {
  32. return fallback(original);
  33. }
  34. return min;
  35. }
  36. public bool Validate(object? value)
  37. {
  38. object lastValue = value;
  39. foreach (var rule in Rules)
  40. {
  41. var (isValid, toPass) = rule(lastValue);
  42. lastValue = toPass;
  43. if (!isValid)
  44. {
  45. return false;
  46. }
  47. }
  48. return true;
  49. }
  50. public object? GetClosestValidValue(object? o)
  51. {
  52. return Rules.Aggregate(o, (current, rule) => rule(current).closestValidValue);
  53. }
  54. }