Got at least one data fetching method working; turns out, we can't use a patched LogicStack to get the data
This commit is contained in:
21
Vendor/Swan.Lite-3.1.0/Validators/IValidator.cs
vendored
Normal file
21
Vendor/Swan.Lite-3.1.0/Validators/IValidator.cs
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace Swan.Validators
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple Validator interface.
|
||||
/// </summary>
|
||||
public interface IValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// The error message.
|
||||
/// </summary>
|
||||
string ErrorMessage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a value is valid.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type.</typeparam>
|
||||
/// <param name="value"> The value.</param>
|
||||
/// <returns>True if it is valid.False if it is not.</returns>
|
||||
bool IsValid<T>(T value);
|
||||
}
|
||||
}
|
||||
58
Vendor/Swan.Lite-3.1.0/Validators/ObjectValidationResult.cs
vendored
Normal file
58
Vendor/Swan.Lite-3.1.0/Validators/ObjectValidationResult.cs
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Swan.Validators
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a validation result containing all validation errors and their properties.
|
||||
/// </summary>
|
||||
public class ObjectValidationResult
|
||||
{
|
||||
private readonly List<ValidationError> _errors = new List<ValidationError>();
|
||||
|
||||
/// <summary>
|
||||
/// A list of errors.
|
||||
/// </summary>
|
||||
public IReadOnlyList<ValidationError> Errors => _errors;
|
||||
|
||||
/// <summary>
|
||||
/// <c>true</c> if there are no errors; otherwise, <c>false</c>.
|
||||
/// </summary>
|
||||
public bool IsValid => !Errors.Any();
|
||||
|
||||
/// <summary>
|
||||
/// Adds an error with a specified property name.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">The property name.</param>
|
||||
/// <param name="errorMessage">The error message.</param>
|
||||
public void Add(string propertyName, string errorMessage) =>
|
||||
_errors.Add(new ValidationError(errorMessage, propertyName));
|
||||
|
||||
/// <summary>
|
||||
/// Defines a validation error.
|
||||
/// </summary>
|
||||
public class ValidationError
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ValidationError"/> class.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property.</param>
|
||||
/// <param name="errorMessage">The error message.</param>
|
||||
public ValidationError(string propertyName, string errorMessage)
|
||||
{
|
||||
PropertyName = propertyName;
|
||||
ErrorMessage = errorMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The property name.
|
||||
/// </summary>
|
||||
public string PropertyName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The message error.
|
||||
/// </summary>
|
||||
public string ErrorMessage { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
173
Vendor/Swan.Lite-3.1.0/Validators/ObjectValidator.cs
vendored
Normal file
173
Vendor/Swan.Lite-3.1.0/Validators/ObjectValidator.cs
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using Swan.Reflection;
|
||||
|
||||
namespace Swan.Validators
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an object validator.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// The following code describes how to perform a simple object validation.
|
||||
/// <code>
|
||||
/// using Swan.Validators;
|
||||
///
|
||||
/// class Example
|
||||
/// {
|
||||
/// public static void Main()
|
||||
/// {
|
||||
/// // create an instance of ObjectValidator
|
||||
/// var obj = new ObjectValidator();
|
||||
///
|
||||
/// // Add a validation to the 'Simple' class with a custom error message
|
||||
/// obj.AddValidator<Simple>(x =>
|
||||
/// !string.IsNullOrEmpty(x.Name), "Name must not be empty");
|
||||
///
|
||||
/// // check if object is valid
|
||||
/// var res = obj.IsValid(new Simple { Name = "Name" });
|
||||
/// }
|
||||
///
|
||||
/// class Simple
|
||||
/// {
|
||||
/// public string Name { get; set; }
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
///
|
||||
/// The following code shows of to validate an object with a custom validator and some attributes using the Runtime ObjectValidator singleton.
|
||||
/// <code>
|
||||
/// using Swan.Validators;
|
||||
///
|
||||
/// class Example
|
||||
/// {
|
||||
/// public static void Main()
|
||||
/// {
|
||||
/// // create an instance of ObjectValidator
|
||||
/// Runtime.ObjectValidator
|
||||
/// .AddValidator<Simple>(x =>
|
||||
/// !x.Name.Equals("Name"), "Name must not be 'Name'");
|
||||
///
|
||||
/// // validate object
|
||||
/// var res = Runtime.ObjectValidator
|
||||
/// .Validate(new Simple{ Name = "name", Number = 5, Email ="email@mail.com"})
|
||||
/// }
|
||||
///
|
||||
/// class Simple
|
||||
/// {
|
||||
/// [NotNull]
|
||||
/// public string Name { get; set; }
|
||||
///
|
||||
/// [Range(1, 10)]
|
||||
/// public int Number { get; set; }
|
||||
///
|
||||
/// [Email]
|
||||
/// public string Email { get; set; }
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
public class ObjectValidator
|
||||
{
|
||||
private static readonly Lazy<ObjectValidator> LazyInstance = new Lazy<ObjectValidator>(() => new ObjectValidator());
|
||||
|
||||
private readonly ConcurrentDictionary<Type, List<Tuple<Delegate, string>>> _predicates =
|
||||
new ConcurrentDictionary<Type, List<Tuple<Delegate, string>>>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current.
|
||||
/// </value>
|
||||
public static ObjectValidator Current => LazyInstance.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Validates an object given the specified validators and attributes.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object.</typeparam>
|
||||
/// <param name="target">The object.</param>
|
||||
/// <returns cref="ObjectValidationResult">A validation result. </returns>
|
||||
public ObjectValidationResult Validate<T>(T target)
|
||||
{
|
||||
var errorList = new ObjectValidationResult();
|
||||
ValidateObject(target, false, errorList.Add);
|
||||
|
||||
return errorList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates an object given the specified validators and attributes.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type.</typeparam>
|
||||
/// <param name="target">The object.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified object is valid; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">obj.</exception>
|
||||
public bool IsValid<T>(T target) => ValidateObject(target);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a validator to a specific class.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object.</typeparam>
|
||||
/// <param name="predicate">The predicate that will be evaluated.</param>
|
||||
/// <param name="message">The message.</param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// predicate
|
||||
/// or
|
||||
/// message.
|
||||
/// </exception>
|
||||
public void AddValidator<T>(Predicate<T> predicate, string message)
|
||||
where T : class
|
||||
{
|
||||
if (predicate == null)
|
||||
throw new ArgumentNullException(nameof(predicate));
|
||||
|
||||
if (string.IsNullOrEmpty(message))
|
||||
throw new ArgumentNullException(message);
|
||||
|
||||
if (!_predicates.TryGetValue(typeof(T), out var existing))
|
||||
{
|
||||
existing = new List<Tuple<Delegate, string>>();
|
||||
_predicates[typeof(T)] = existing;
|
||||
}
|
||||
|
||||
existing.Add(Tuple.Create((Delegate)predicate, message));
|
||||
}
|
||||
|
||||
private bool ValidateObject<T>(T obj, bool returnOnError = true, Action<string, string>? action = null)
|
||||
{
|
||||
if (Equals(obj, null))
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
|
||||
if (_predicates.ContainsKey(typeof(T)))
|
||||
{
|
||||
foreach (var (@delegate, value) in _predicates[typeof(T)])
|
||||
{
|
||||
if ((bool)@delegate.DynamicInvoke(obj)) continue;
|
||||
|
||||
action?.Invoke(value, string.Empty);
|
||||
if (returnOnError) return false;
|
||||
}
|
||||
}
|
||||
|
||||
var properties = AttributeCache.DefaultCache.Value.RetrieveFromType<T, IValidator>();
|
||||
|
||||
foreach (var prop in properties)
|
||||
{
|
||||
foreach (var attribute in prop.Value)
|
||||
{
|
||||
var val = (IValidator)attribute;
|
||||
|
||||
if (val.IsValid(prop.Key.GetValue(obj, null))) continue;
|
||||
|
||||
action?.Invoke(val.ErrorMessage, prop.Key.Name);
|
||||
if (returnOnError) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
132
Vendor/Swan.Lite-3.1.0/Validators/Validators.cs
vendored
Normal file
132
Vendor/Swan.Lite-3.1.0/Validators/Validators.cs
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Swan.Validators
|
||||
{
|
||||
/// <summary>
|
||||
/// Regex validator.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class MatchAttribute : Attribute, IValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MatchAttribute" /> class.
|
||||
/// </summary>
|
||||
/// <param name="regex">A regex string.</param>
|
||||
/// <param name="errorMessage">The error message.</param>
|
||||
/// <exception cref="ArgumentNullException">Expression.</exception>
|
||||
public MatchAttribute(string regex, string? errorMessage = null)
|
||||
{
|
||||
Expression = regex ?? throw new ArgumentNullException(nameof(regex));
|
||||
ErrorMessage = errorMessage ?? "String does not match the specified regular expression";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The string regex used to find a match.
|
||||
/// </summary>
|
||||
public string Expression { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ErrorMessage { get; internal set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsValid<T>(T value)
|
||||
{
|
||||
if (Equals(value, default(T)))
|
||||
return false;
|
||||
|
||||
return !(value is string)
|
||||
? throw new ArgumentException("Property is not a string")
|
||||
: Regex.IsMatch(value.ToString(), Expression);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Email validator.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class EmailAttribute : MatchAttribute
|
||||
{
|
||||
private const string EmailRegExp =
|
||||
@"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
|
||||
@"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-0-9a-z]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EmailAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="errorMessage">The error message.</param>
|
||||
public EmailAttribute(string? errorMessage = null)
|
||||
: base(EmailRegExp, errorMessage ?? "String is not an email")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A not null validator.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class NotNullAttribute : Attribute, IValidator
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string ErrorMessage => "Value is null";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsValid<T>(T value) => !Equals(default(T), value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A range constraint validator.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class RangeAttribute : Attribute, IValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RangeAttribute"/> class.
|
||||
/// Constructor that takes integer minimum and maximum values.
|
||||
/// </summary>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
public RangeAttribute(int min, int max)
|
||||
{
|
||||
if (min >= max)
|
||||
throw new InvalidOperationException("Maximum value must be greater than minimum");
|
||||
|
||||
Maximum = max;
|
||||
Minimum = min;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RangeAttribute"/> class.
|
||||
/// Constructor that takes double minimum and maximum values.
|
||||
/// </summary>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
public RangeAttribute(double min, double max)
|
||||
{
|
||||
if (min >= max)
|
||||
throw new InvalidOperationException("Maximum value must be greater than minimum");
|
||||
|
||||
Maximum = max;
|
||||
Minimum = min;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ErrorMessage => "Value is not within the specified range";
|
||||
|
||||
/// <summary>
|
||||
/// Maximum value for the range.
|
||||
/// </summary>
|
||||
public IComparable Maximum { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum value for the range.
|
||||
/// </summary>
|
||||
public IComparable Minimum { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsValid<T>(T value)
|
||||
=> value is IComparable comparable
|
||||
? comparable.CompareTo(Minimum) >= 0 && comparable.CompareTo(Maximum) <= 0
|
||||
: throw new ArgumentException(nameof(value));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user