using LanguageExt.Common;
using LanguageExt.TypeClasses;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Utils {
// YYC MARK:
// 这些验证器尽管服务于UI,但是并不遵循WPF或者CommunityToolkit.Mvvm的Validator模型,
// 所以我把他们放在这里。
///
/// 验证器接口。
///
/// 验证器接受的待验证数据的类型。
/// 验证器验证完毕后,会输出的类型。
public interface IValidator {
///
/// 验证给定数据是否正确。
///
/// 要验证的数据。
/// 数据正确,或对应的错误信息。
ValidationResult Validate(TIn data);
///
/// 获取验证无误数据转换后的数据。
///
/// 验证无误,用于获取输出的数据。
/// 输出的数据。
/// 给定数据验证时出现错误。
TOut Fetch(TIn data);
}
///
/// 以字符串呈现的数据的通用验证器
///
public abstract class StringifiedValueValidator : IValidator where T : notnull {
///
/// 用户需要实现的验证函数。
///
/// 要进行验证的数据。
/// 验证完毕用于输出的数值,或者验证失败时的错误消息。
protected abstract Either ValidateValue(string stringifiedValue);
public ValidationResult Validate(string data) {
return ValidateValue(data).Match(
Left: (_) => ValidationResult.Success,
Right: (v) => new ValidationResult(v)
);
}
public T Fetch(string data) {
return ValidateValue(data).Match(
Left: (v) => v,
Right: (msg) => throw new ArgumentException($"Given value can not pass Validator due to {msg}.")
);
}
}
public abstract class IntegerValidator : StringifiedValueValidator {
protected override Either ValidateValue(string stringifiedValue) {
if (int.TryParse(stringifiedValue, out int val)) {
return Left(val);
} else {
return Right("Given string do not represent any valid number.");
}
}
}
public class FpsValidator : IntegerValidator {
public static FpsValidator Instance = new FpsValidator();
protected override Either ValidateValue(string stringifiedValue) {
return base.ValidateValue(stringifiedValue).BindLeft((v) => {
if (v <= 0) return Right("Fps must be greater than zero.");
else return Left(v);
});
}
}
public class CountValidator : IntegerValidator {
public static FpsValidator Instance = new FpsValidator();
protected override Either ValidateValue(string stringifiedValue) {
return base.ValidateValue(stringifiedValue).BindLeft((v) => {
if (v < 0) return Right("Count can not lower than zero.");
else return Left(v);
});
}
}
}