RaspberryIO/Unosquare.Swan.Lite/Attributes/Validators.cs
2019-12-04 17:10:06 +01:00

130 lines
4.2 KiB
C#

using System;
using System.Text.RegularExpressions;
using Unosquare.Swan.Abstractions;
namespace Unosquare.Swan.Attributes {
/// <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) {
this.Expression = regex ?? throw new ArgumentNullException(nameof(this.Expression));
this.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 Boolean IsValid<T>(T value) => Equals(value, default(T))
? false
: !(value is String)
? throw new ArgumentException("Property is not a string")
: Regex.IsMatch(value.ToString(), this.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 Boolean 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(Int32 min, Int32 max) {
if(min >= max) {
throw new InvalidOperationException("Maximum value must be greater than minimum");
}
this.Maximum = max;
this.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");
}
this.Maximum = max;
this.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 Boolean IsValid<T>(T value)
=> value is IComparable comparable
? comparable.CompareTo(this.Minimum) >= 0 && comparable.CompareTo(this.Maximum) <= 0
: throw new ArgumentException(nameof(value));
}
}