20221130
This commit is contained in:
63
anbs_cp/Classes/ActionError.cs
Normal file
63
anbs_cp/Classes/ActionError.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using anbs_cp.Interfaces;
|
||||
|
||||
namespace anbs_cp.Classes;
|
||||
|
||||
/// <summary>
|
||||
/// Класс ошибки
|
||||
/// </summary>
|
||||
public sealed class ActionError: IActionError
|
||||
{
|
||||
/// <summary>
|
||||
/// Критичность ошибки:
|
||||
/// при некритичных ошибках продолжение выполнения операции возможно,
|
||||
/// а при критичных -- нет
|
||||
/// </summary>
|
||||
public bool IsCritical { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Объект ошибки
|
||||
/// </summary>
|
||||
public object Object { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Сообщение об ошибке
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
#region Конструкторы
|
||||
/// <summary>
|
||||
/// Конструктор по умолчанию
|
||||
/// </summary>
|
||||
public ActionError ()
|
||||
{
|
||||
IsCritical = true;
|
||||
Object = "Not Implemented";
|
||||
Message = "Not Implemented";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Конструктор с 2 параметрами
|
||||
/// </summary>
|
||||
/// <param name="message">Сообщение</param>
|
||||
/// <param name="isCritical">Критичность ошибки</param>
|
||||
public ActionError (string message, bool isCritical = true)
|
||||
{
|
||||
IsCritical = isCritical;
|
||||
Object = "";
|
||||
Message = message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Конструктор с 3 параметрами
|
||||
/// </summary>
|
||||
/// <param name="eObject">Объект ошибки</param>
|
||||
/// <param name="message">Сообщение</param>
|
||||
/// <param name="isCritical">Критичность ошибки</param>
|
||||
public ActionError (object eObject, string message, bool isCritical = true)
|
||||
{
|
||||
IsCritical = isCritical;
|
||||
Object = eObject;
|
||||
Message = message;
|
||||
}
|
||||
#endregion
|
||||
}
|
49
anbs_cp/Classes/ActionInfo.cs
Normal file
49
anbs_cp/Classes/ActionInfo.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using anbs_cp.Interfaces;
|
||||
|
||||
namespace anbs_cp.Classes;
|
||||
|
||||
/// <summary>
|
||||
/// Класс предупреждения
|
||||
/// </summary>
|
||||
public sealed class ActionInfo: IActionInfo
|
||||
{
|
||||
#region Конструкторы
|
||||
/// <summary>
|
||||
/// Конструктор по умолчанию
|
||||
/// </summary>
|
||||
public ActionInfo ()
|
||||
{
|
||||
IsStatusInfo = false;
|
||||
Object = string.Empty;
|
||||
Message = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Конструктор
|
||||
/// </summary>
|
||||
/// <param name="eObject">Объект</param>
|
||||
/// <param name="message">Сообщение</param>
|
||||
/// <param name="isStatus">Является статусной информацией?</param>
|
||||
public ActionInfo (string eObject, string message, bool isStatus = false)
|
||||
{
|
||||
IsStatusInfo = isStatus;
|
||||
Object = eObject;
|
||||
Message = message;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Реализация интерфейса
|
||||
/// <summary>
|
||||
/// Объект
|
||||
/// </summary>
|
||||
public object Object { get; set; }
|
||||
/// <summary>
|
||||
/// Сообщение
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
/// <summary>
|
||||
/// Статусная информация (например, начало работы)
|
||||
/// </summary>
|
||||
public bool IsStatusInfo { get; init; }
|
||||
#endregion
|
||||
}
|
299
anbs_cp/Classes/ActionState.cs
Normal file
299
anbs_cp/Classes/ActionState.cs
Normal file
@@ -0,0 +1,299 @@
|
||||
using anbs_cp.Interfaces;
|
||||
|
||||
namespace anbs_cp.Classes;
|
||||
|
||||
/// <summary>
|
||||
/// Состояние действия
|
||||
/// </summary>
|
||||
public sealed class ActionState
|
||||
{
|
||||
/// <summary>
|
||||
/// Конструктор
|
||||
/// </summary>
|
||||
public ActionState ()
|
||||
{
|
||||
Info = new();
|
||||
Warnings = new();
|
||||
Errors = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Список информации
|
||||
/// </summary>
|
||||
public List<IActionInfo> Info { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Список предупреждений
|
||||
/// </summary>
|
||||
public List<IActionWarning> Warnings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Список ошибок
|
||||
/// </summary>
|
||||
public List<IActionError> Errors { get; }
|
||||
|
||||
#region Методы
|
||||
|
||||
#region Очистка
|
||||
/// <summary>
|
||||
/// Очищает список ошибок
|
||||
/// </summary>
|
||||
public void ClearErrors ()
|
||||
{
|
||||
Errors.Clear();
|
||||
Errors.TrimExcess();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Очищает список предупреждений
|
||||
/// </summary>
|
||||
public void ClearWarnings ()
|
||||
{
|
||||
Warnings.Clear();
|
||||
Warnings.TrimExcess();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Очищает список информации
|
||||
/// </summary>
|
||||
public void ClearInfo ()
|
||||
{
|
||||
Info.Clear();
|
||||
Info.TrimExcess();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Очищает все списки
|
||||
/// </summary>
|
||||
public void Clear ()
|
||||
{
|
||||
ClearInfo();
|
||||
ClearWarnings();
|
||||
ClearErrors();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Добавление ошибки
|
||||
/// <summary>
|
||||
/// Добавление ошибки
|
||||
/// </summary>
|
||||
/// <param name="error">Ошибка</param>
|
||||
// ReSharper disable once MemberCanBeMadeStatic.Global
|
||||
// ReSharper disable once FunctionRecursiveOnAllPaths
|
||||
public void AddError (IActionError error) => AddError(error);
|
||||
|
||||
/// <summary>
|
||||
/// Добавляет ошибки в список
|
||||
/// </summary>
|
||||
/// <param name="errors">Список ошибок</param>
|
||||
public void AddErrors(IEnumerable<IActionError> errors) => Errors.AddRange(errors);
|
||||
|
||||
/// <summary>
|
||||
/// Добавление ошибки
|
||||
/// </summary>
|
||||
/// <param name="critical">Является ли ошибка критической</param>
|
||||
public void AddError (bool critical = true)
|
||||
{
|
||||
//Создаю ошибку
|
||||
ActionError error = new("", critical);
|
||||
|
||||
//Добавляю ошибку
|
||||
AddError(error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавление ошибки
|
||||
/// </summary>
|
||||
/// <param name="message">Сообщение об ошибке</param>
|
||||
/// <param name="critical">Является ли ошибка критической</param>
|
||||
public void AddError (string message, bool critical = true)
|
||||
{
|
||||
//Создаю ошибку
|
||||
ActionError error = new(message, critical);
|
||||
|
||||
//Добавляю ошибку
|
||||
AddError(error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавление ошибки
|
||||
/// </summary>
|
||||
/// <param name="errorObject">Объект ошибки</param>
|
||||
/// <param name="message">Сообщение об ошибке</param>
|
||||
/// /// <param name="critical">Является ли ошибка критической</param>
|
||||
public void AddError (string errorObject, string message, bool critical = true)
|
||||
{
|
||||
//Создаю ошибку
|
||||
ActionError error = new(errorObject, message, critical);
|
||||
|
||||
//Добавляю ошибку
|
||||
AddError(error);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Добавление предупреждения
|
||||
/// <summary>
|
||||
/// Добавление предупреждения
|
||||
/// </summary>
|
||||
/// <param name="warning">Предупреждение</param>
|
||||
public void AddWarning (IActionWarning warning) => Warnings.Add(warning);
|
||||
|
||||
/// <summary>
|
||||
/// Добавление предупреждений
|
||||
/// </summary>
|
||||
/// <param name="warnings">Список предупреждений</param>
|
||||
public void AddWarnings(IEnumerable<IActionWarning> warnings) => Warnings.AddRange(warnings);
|
||||
|
||||
/// <summary>
|
||||
/// Добавление предупреждение
|
||||
/// </summary>
|
||||
/// <param name="message">Текст предупреждения</param>
|
||||
/// <param name="warningObject">Объект предупреждения</param>
|
||||
public void AddWarning (string message, string warningObject = "")
|
||||
{
|
||||
//Создаю предупреждение
|
||||
ActionWarning warning = new(warningObject, message);
|
||||
|
||||
//Добавляю предупреждение
|
||||
AddWarning(warning);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Добавление информации
|
||||
/// <summary>
|
||||
/// Добавление информации
|
||||
/// </summary>
|
||||
/// <param name="info">Информация</param>
|
||||
public void AddInfo (IActionInfo info) => Info.Add(info);
|
||||
|
||||
/// <summary>
|
||||
/// Добавление информации
|
||||
/// </summary>
|
||||
/// <param name="infos">Список информации</param>
|
||||
public void AddInfos (IEnumerable<IActionInfo> infos) => Info.AddRange(infos);
|
||||
|
||||
/// <summary>
|
||||
/// Добавление информации
|
||||
/// </summary>
|
||||
/// <param name="message">Текст информации</param>
|
||||
/// <param name="warningObject">Объект информации</param>
|
||||
public void AddInfo (string message, string warningObject = "")
|
||||
{
|
||||
//Создаю информацию
|
||||
ActionInfo info = new(warningObject, message);
|
||||
|
||||
//Добавляю информацию
|
||||
AddInfo(info);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Печать
|
||||
/// <summary>
|
||||
/// Печать списка ошибок
|
||||
/// </summary>
|
||||
/// <param name="formatList">Формат списка</param>
|
||||
/// <param name="formatItem">Формат элемента списка</param>
|
||||
/// <returns>Список ошибок в текстовой форме</returns>
|
||||
public string PrintErrorList (string formatList, string formatItem)
|
||||
{
|
||||
string elements =
|
||||
#pragma warning disable CS8625
|
||||
Errors.Aggregate<IActionError, string>(null, (current, error) => current + error.PrintMessage(formatItem));
|
||||
#pragma warning restore CS8625
|
||||
|
||||
return string.Format(formatList, elements);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Печать списка предупреждений
|
||||
/// </summary>
|
||||
/// <param name="formatList">Формат списка</param>
|
||||
/// <param name="formatItem">Формат элемента списка</param>
|
||||
/// <returns>Список предупреждений в текстовой форме</returns>
|
||||
public string PrintWarningList (string formatList, string formatItem)
|
||||
{
|
||||
string elements =
|
||||
#pragma warning disable CS8625
|
||||
Warnings.Aggregate<IActionWarning, string>(null,
|
||||
#pragma warning restore CS8625
|
||||
(current, warning) => current + warning.PrintMessage(formatItem));
|
||||
|
||||
return string.Format(formatList, elements);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Печать списка информации
|
||||
/// </summary>
|
||||
/// <param name="formatList">Формат списка</param>
|
||||
/// <param name="formatItem">Формат элемента списка</param>
|
||||
/// <returns>Список информации в текстовой форме</returns>
|
||||
public string PrintInfoList (string formatList, string formatItem)
|
||||
{
|
||||
string elements =
|
||||
#pragma warning disable CS8625
|
||||
Info.Aggregate<IActionInfo, string>(null, (current, info) => current + info.PrintMessage(formatItem));
|
||||
#pragma warning restore CS8625
|
||||
|
||||
return string.Format(formatList, elements);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Проверка на наличие
|
||||
/// <summary>
|
||||
/// Проверяет, есть ли ошибки
|
||||
/// </summary>
|
||||
/// <param name="ignoreNonCritical">Игнорировать не критические</param>
|
||||
/// <returns>Наличие ошибок</returns>
|
||||
public bool HasErrors (bool ignoreNonCritical = false) =>
|
||||
ignoreNonCritical ? Errors.Any(static error => error.IsCritical) : Errors.Any();
|
||||
|
||||
/// <summary>
|
||||
/// Проверяет, есть ли предупреждения
|
||||
/// </summary>
|
||||
/// <param name="ignoreInformWarning">Игнорировать информационные предупреждения</param>
|
||||
/// <returns>Наличие предупреждений</returns>
|
||||
public bool HasWarnings (bool ignoreInformWarning = false) => ignoreInformWarning
|
||||
? Warnings.Any(static warning => !warning.IsInformWarning)
|
||||
: Warnings.Any();
|
||||
|
||||
/// <summary>
|
||||
/// Проверяет, есть ли сообщения
|
||||
/// </summary>
|
||||
/// <param name="ignoreStatus">Игнорировать статусные сообщения</param>
|
||||
/// <returns>Наличие сообщений</returns>
|
||||
public bool HasInfo (bool ignoreStatus) => ignoreStatus ? Info.Any(static info => !info.IsStatusInfo) : Info.Any();
|
||||
|
||||
/// <summary>
|
||||
/// Успешно ли завершилось
|
||||
/// </summary>
|
||||
public bool IsSuccess (bool ignoreNonCriticalErrors = false) =>
|
||||
!HasErrors(ignoreNonCriticalErrors) && !HasWarnings(true);
|
||||
#endregion
|
||||
|
||||
#region Количество сообщений
|
||||
/// <summary>
|
||||
/// Количество ошибок
|
||||
/// </summary>
|
||||
/// <param name="ignoreNonCritical">Игнорировать не критические</param>
|
||||
/// <returns>Количество ошибок</returns>
|
||||
public int ErrorsCount (bool ignoreNonCritical = false) =>
|
||||
ignoreNonCritical ? Errors.Count(static error => error.IsCritical) : Errors.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Количество предупреждений
|
||||
/// </summary>
|
||||
/// <param name="ignoreInformWarning">Игнорировать информационные предупреждения</param>
|
||||
/// <returns>Количество предупреждений</returns>
|
||||
public int WarningsCount (bool ignoreInformWarning = false) => ignoreInformWarning
|
||||
? Warnings.Count(static warning => !warning.IsInformWarning)
|
||||
: Warnings.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Количество информационных сообщений
|
||||
/// </summary>
|
||||
/// <param name="ignoreStatus">Игнорировать статусные сообщения</param>
|
||||
/// <returns>Количество информационных сообщений</returns>
|
||||
public int InfoCount (bool ignoreStatus) => ignoreStatus ? Info.Count(static info => !info.IsStatusInfo) : Info.Count;
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
49
anbs_cp/Classes/ActionWarning.cs
Normal file
49
anbs_cp/Classes/ActionWarning.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using anbs_cp.Interfaces;
|
||||
|
||||
namespace anbs_cp.Classes;
|
||||
|
||||
/// <summary>
|
||||
/// Класс предупреждения
|
||||
/// </summary>
|
||||
public sealed class ActionWarning: IActionWarning
|
||||
{
|
||||
#region Конструкторы
|
||||
/// <summary>
|
||||
/// Конструктор по умолчанию
|
||||
/// </summary>
|
||||
public ActionWarning ()
|
||||
{
|
||||
IsInformWarning = false;
|
||||
Object = string.Empty;
|
||||
Message = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Конструктор
|
||||
/// </summary>
|
||||
/// <param name="eObject">Объект</param>
|
||||
/// <param name="message">Сообщение</param>
|
||||
/// <param name="isInform">Является ли информирующим предупреждением</param>
|
||||
public ActionWarning (string eObject, string message, bool isInform = false)
|
||||
{
|
||||
IsInformWarning = isInform;
|
||||
Object = eObject;
|
||||
Message = message;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Реализация интерфейса
|
||||
/// <summary>
|
||||
/// Объект
|
||||
/// </summary>
|
||||
public object Object { get; set; }
|
||||
/// <summary>
|
||||
/// Сообщение
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
/// <summary>
|
||||
/// Информирующее предупреждение возникает для предупреждения ВОЗМОЖНОЙ ошибки в дальнейшей эксплуатации и не влияет на текущую операцию.
|
||||
/// </summary>
|
||||
public bool IsInformWarning { get; init; }
|
||||
#endregion
|
||||
}
|
48
anbs_cp/Classes/CountFormatter.cs
Normal file
48
anbs_cp/Classes/CountFormatter.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
namespace anbs_cp.Classes;
|
||||
|
||||
/// <summary>
|
||||
/// Форматирует число элементов в понятную строку
|
||||
/// </summary>
|
||||
public sealed class CountFormatter : IValueFormatter
|
||||
{
|
||||
#region Cвойства класса
|
||||
|
||||
/// <summary>
|
||||
/// Имена чисел (тысяч, миллионов, миллиардов и т.п.)
|
||||
/// </summary>
|
||||
public string[] CountNames { get; set; } = { "", "тыс.", "млн.", "млрд." };
|
||||
|
||||
/// <summary>
|
||||
/// Знаков после запятой
|
||||
/// </summary>
|
||||
public byte DecimalPlaces { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Делители чисел
|
||||
/// </summary>
|
||||
public long[] Delimeters { get; set; } = { 1000, 1000000, 1000000000 };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Реализация интерфейса
|
||||
|
||||
/// <summary>
|
||||
/// Реализация интерфейса
|
||||
/// </summary>
|
||||
public string[] ValueNames
|
||||
{
|
||||
get => CountNames;
|
||||
set => CountNames = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Реализация интерфейса
|
||||
/// </summary>
|
||||
public long[] MaxSizes
|
||||
{
|
||||
get => Delimeters;
|
||||
set => Delimeters = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
69
anbs_cp/Classes/FileSizeFormatter.cs
Normal file
69
anbs_cp/Classes/FileSizeFormatter.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
namespace anbs_cp.Classes;
|
||||
|
||||
/// <summary>
|
||||
/// Форматирует размер файла/папки в понятную строку
|
||||
/// </summary>
|
||||
public class FileSizeFormatter : IValueFormatter
|
||||
{
|
||||
#region Cвойства класса
|
||||
|
||||
/// <summary>
|
||||
/// Имена размеров (байт, килобайт, мегабайт, гигабайт и террабайт)
|
||||
/// </summary>
|
||||
public string[] SizeNames { get; set; } = { "Байт", "Кб", "Мб", "Гб", "Тб" };
|
||||
|
||||
/// <summary>
|
||||
/// Знаков после запятой
|
||||
/// </summary>
|
||||
public byte DecimalPlaces { get; set; } = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Максимально байт (далее идут Кбайты)
|
||||
/// </summary>
|
||||
public long ByteMax { get; set; } = 1024;
|
||||
|
||||
/// <summary>
|
||||
/// Максимально Кбайт (далее идут Мбайты)
|
||||
/// </summary>
|
||||
public long KByteMax { get; set; } = 1048576;
|
||||
|
||||
/// <summary>
|
||||
/// Максимально Мбайт (далее идут Гбайты)
|
||||
/// </summary>
|
||||
public long MByteMax { get; set; } = 1073741824;
|
||||
|
||||
/// <summary>
|
||||
/// Максимально Гбайт (далее идут Тбайты)
|
||||
/// </summary>
|
||||
public long GByteMax { get; set; } = 1099511627776;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Реализация интерфейса
|
||||
|
||||
/// <summary>
|
||||
/// Реализация интерфейса
|
||||
/// </summary>
|
||||
public string[] ValueNames
|
||||
{
|
||||
get => SizeNames;
|
||||
set => SizeNames = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Реализация интерфейса
|
||||
/// </summary>
|
||||
public long[] MaxSizes
|
||||
{
|
||||
get => new[] { ByteMax, KByteMax, MByteMax, GByteMax };
|
||||
set
|
||||
{
|
||||
ByteMax = value[0];
|
||||
KByteMax = value[1];
|
||||
MByteMax = value[2];
|
||||
GByteMax = value[3];
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
74
anbs_cp/Classes/IValueFormatter.cs
Normal file
74
anbs_cp/Classes/IValueFormatter.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
namespace anbs_cp.Classes;
|
||||
|
||||
/// <summary>
|
||||
/// Форматирует размерности в понятную строку
|
||||
/// </summary>
|
||||
public interface IValueFormatter
|
||||
{
|
||||
#region Определения интерфейса
|
||||
|
||||
/// <summary>
|
||||
/// Имена размерностей
|
||||
/// </summary>
|
||||
public string[] ValueNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Знаков после запятой
|
||||
/// </summary>
|
||||
public byte DecimalPlaces { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Максимальные размеры (массив ulong[4])
|
||||
/// </summary>
|
||||
public long[] MaxSizes { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Методы интерфейса
|
||||
|
||||
/// <summary>
|
||||
/// Форматирование размерности
|
||||
/// </summary>
|
||||
/// <param name="value">Размерность, требующая форматирования</param>
|
||||
/// <returns>Форматированная размерность (например, 20 Мб)</returns>
|
||||
public string Format(long value)
|
||||
{
|
||||
//Левая граница
|
||||
long leftnum;
|
||||
//Правая граница
|
||||
long rightnum;
|
||||
|
||||
for (int i = 0; i <= MaxSizes.Length; i++)
|
||||
{
|
||||
leftnum = i == 0 ? 0 : MaxSizes[i - 1];
|
||||
|
||||
rightnum = i == MaxSizes.Length ? long.MaxValue : MaxSizes[i];
|
||||
|
||||
if (value >= leftnum && value < rightnum)
|
||||
return $"{FormatValue(value, leftnum)} {ValueNames[i]}";
|
||||
}
|
||||
|
||||
return value.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Деление числа на число с DecimalPlaces знаками после запятой
|
||||
/// </summary>
|
||||
/// <param name="dividend">Делимое число</param>
|
||||
/// <param name="divider">Число-делитель</param>
|
||||
/// <returns>Частное (с DecimalPlaces знаками после запятой)</returns>
|
||||
private string FormatValue(long dividend, long divider)
|
||||
{
|
||||
if (divider == 0) return $"{dividend}";
|
||||
|
||||
long delim = 1;
|
||||
|
||||
for (int i = 0; i <= DecimalPlaces; i++) delim *= 10;
|
||||
|
||||
decimal value = Math.Round((decimal)(dividend * delim / divider)) / delim;
|
||||
|
||||
return $"{value}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
33
anbs_cp/Classes/LikeDelphi.cs
Normal file
33
anbs_cp/Classes/LikeDelphi.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
namespace anbs_cp.Classes;
|
||||
|
||||
/// <summary>
|
||||
/// Класс, добавляющий реализацию некоторых методов Delphi, которые упрощают работу в C#.
|
||||
/// </summary>
|
||||
public static class LikeDelphi
|
||||
{
|
||||
/// <summary>
|
||||
/// Аналог функции IncludeTrailingBackslash
|
||||
/// </summary>
|
||||
/// <param name="path">Путь, к которому нужно добавить slash</param>
|
||||
/// <returns>Путь со slash в конце</returns>
|
||||
public static string IncludeTrailingBackslash(string path)
|
||||
{
|
||||
//По умолчанию сохраняем путь
|
||||
string result = path;
|
||||
|
||||
//Если последний символ не "\", то добавим "\" в конце
|
||||
if (path[^1] != '\\')
|
||||
result = $@"{path}\";
|
||||
|
||||
//Вернём результат
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Парсер строки в множество строк
|
||||
/// </summary>
|
||||
/// <param name="str">Строка, которую нужно разбить</param>
|
||||
/// <param name="delimiter">Символ-делитель строки</param>
|
||||
/// <returns>Массив строк</returns>
|
||||
public static List<string> ParseString(string str, char delimiter) => str.Split(delimiter).ToList();
|
||||
}
|
133
anbs_cp/Classes/SimpleMapper.cs
Normal file
133
anbs_cp/Classes/SimpleMapper.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace anbs_cp.Classes;
|
||||
|
||||
/// <summary>
|
||||
/// Класс перевода одинаковых свойств из класса TF в класс T.
|
||||
/// Оригинальные автор(-ы): keenthinker и Avtandil Kavrelishvili.
|
||||
/// Улучшения: А. Н. Бабаев
|
||||
/// URL: https://stackoverflow.com/questions/20410234/how-to-automatically-map-the-values-between-instances-of-two-different-classes-i
|
||||
/// </summary>
|
||||
public static class SimpleMapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Перевод одинаковых свойств из класса F в класс TT.
|
||||
/// </summary>
|
||||
/// <param name="from">Экземпляр класса F</param>
|
||||
/// <param name="to">Ссылка на экземпляр класса T</param>
|
||||
/// <param name="mode">Тип сопоставления</param>
|
||||
/// <param name="list">Список параметров для сопоставления</param>
|
||||
/// <typeparam name="TF">Класс-родитель</typeparam>
|
||||
/// <typeparam name="T">Класс-приемник</typeparam>
|
||||
public static void MapEx<TF, T>(TF from, ref T to, MapMode mode, List<string> list)
|
||||
{
|
||||
//Копирую поля
|
||||
Type typeOfA = typeof(TF);
|
||||
Type typeOfB = typeof(T);
|
||||
foreach (FieldInfo fieldOfA in typeOfA.GetFields())
|
||||
{
|
||||
//Проверяем выполнение условия и прерываем, если не выполняется
|
||||
if (!CheckCondition<TF>(fieldOfA.Name, fieldOfA.GetValue(from), mode, list))
|
||||
continue;
|
||||
|
||||
//Получаем FieldInfo для b по имени поля a
|
||||
FieldInfo? fieldOfB = typeOfB.GetField(fieldOfA.Name);
|
||||
|
||||
//Присваиваю поля типа B значение поля типа A
|
||||
fieldOfB?.SetValue(to, fieldOfA.GetValue(from));
|
||||
}
|
||||
|
||||
//Копирую свойства
|
||||
foreach (PropertyInfo propertyOfA in typeOfA.GetProperties())
|
||||
{
|
||||
//Проверяем выполнение условия и прерываем, если не выполняется
|
||||
if (!CheckCondition<TF>(propertyOfA.Name, propertyOfA.GetValue(from), mode, list))
|
||||
continue;
|
||||
|
||||
//Получаем PropertyInfo для b по имени свойства a
|
||||
PropertyInfo? propertyOfB = typeOfB.GetProperty(propertyOfA.Name);
|
||||
//Присваиваю свойству типа B значение свойства типа A
|
||||
propertyOfB?.SetValue(to, propertyOfA.GetValue(from));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Перевод одинаковых свойств из класса F в класс TT (режим "сопоставление всех параметров").
|
||||
/// </summary>
|
||||
/// <param name="from">Параметр класса F</param>
|
||||
/// <typeparam name="TF">Класс-родитель</typeparam>
|
||||
/// <typeparam name="T">Класс-приемник</typeparam>
|
||||
/// <returns>Элемент класса T</returns>
|
||||
public static T Map<TF, T>(TF from)
|
||||
{
|
||||
//Создаю элемент
|
||||
// ReSharper disable once NullableWarningSuppressionIsUsed
|
||||
T result = (T)Activator.CreateInstance(typeof(T))!;
|
||||
//Сопоставляю по принципу "сопоставление всех параметров"
|
||||
MapEx(from, ref result, MapMode.MapFull, new());
|
||||
//Вывожу в результат
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверка выполнения условия
|
||||
/// </summary>
|
||||
/// <param name="itemName">Имя элемента</param>
|
||||
/// <param name="itemValue">Значение элемента</param>
|
||||
/// <param name="mode">Режим проверки</param>
|
||||
/// <param name="list">Список игнорирования/добавления</param>
|
||||
/// <returns></returns>
|
||||
private static bool CheckCondition<T>(string itemName, object? itemValue, MapMode mode, ICollection<string> list)
|
||||
{
|
||||
//Если режим "Только список" и поля нет в списке,
|
||||
//либо режим "Только не в списке" и поле есть в списке
|
||||
//или режим "Только не пустые" и значение поля пустое,
|
||||
//или режим "Только не по умолчанию" и значение по умолчанию
|
||||
//то пропускаем
|
||||
bool result =
|
||||
mode switch
|
||||
{
|
||||
MapMode.MapFull => true,
|
||||
MapMode.MapNotNull => itemValue != null,
|
||||
MapMode.MapByList => list.Contains(itemName),
|
||||
MapMode.MapIgnoreList => !list.Contains(itemName),
|
||||
MapMode.MapNotDefault => itemValue != default,
|
||||
MapMode.MapNotNullOrDefault => !Equals(itemValue, default(T)),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null)
|
||||
};
|
||||
|
||||
//Возвращаем результат
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Перечисление типов сопоставления
|
||||
/// </summary>
|
||||
public enum MapMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Сопоставление всех параметров
|
||||
/// </summary>
|
||||
MapFull = 0,
|
||||
/// <summary>
|
||||
/// Сопоставление не пустых параметров
|
||||
/// </summary>
|
||||
MapNotNull = 1,
|
||||
/// <summary>
|
||||
/// Сопоставление по списку
|
||||
/// </summary>
|
||||
MapByList = 2,
|
||||
/// <summary>
|
||||
/// Сопоставление исключая список
|
||||
/// </summary>
|
||||
MapIgnoreList = 3,
|
||||
/// <summary>
|
||||
/// Сопоставление параметров, которые не равны значению по умолчанию
|
||||
/// </summary>
|
||||
MapNotDefault = 4,
|
||||
/// <summary>
|
||||
/// Сопоставление не пустых параметров, которые не равны значению по умолчанию (NotNull и NotDefault одновременно)
|
||||
/// </summary>
|
||||
MapNotNullOrDefault = 5,
|
||||
}
|
||||
}
|
90
anbs_cp/Classes/TimestampValidator.cs
Normal file
90
anbs_cp/Classes/TimestampValidator.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
namespace anbs_cp.Classes;
|
||||
|
||||
/// <summary>
|
||||
/// Класс проверки временного интервала
|
||||
/// </summary>
|
||||
public static class TimestampValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// Проверка попадания в заданный интервал (в мс)
|
||||
/// </summary>
|
||||
/// <param name="timestamp">Временной интервал</param>
|
||||
/// <param name="checkedStamp">Проверяемый временной интервал</param>
|
||||
/// <param name="deltaMs">Временная дельта в миллисекундах</param>
|
||||
/// <returns>
|
||||
/// Попал ли <paramref name="checkedStamp" /> в промежуток <paramref name="timestamp" /> +
|
||||
/// <paramref name="deltaMs" />
|
||||
/// </returns>
|
||||
public static bool Validate(long timestamp, long checkedStamp, ulong deltaMs) =>
|
||||
new TimeSpan(timestamp) + TimeSpan.FromMilliseconds(deltaMs) > new TimeSpan(checkedStamp);
|
||||
|
||||
/// <summary>
|
||||
/// Проверка попадания текущего времени в заданный интервал (в мс)
|
||||
/// </summary>
|
||||
/// <param name="timestamp">Временной интервал</param>
|
||||
/// <param name="deltams">Временная дельта в миллисекундах</param>
|
||||
/// <returns>Попадает ли текущее время в промежуток <paramref name="timestamp" /> + <paramref name="deltams" /></returns>
|
||||
public static bool ValidateNow(long timestamp, ulong deltams) =>
|
||||
Validate(timestamp, DateTime.UtcNow.Ticks, deltams);
|
||||
|
||||
/// <summary>
|
||||
/// Проверка временного интервала (в сек)
|
||||
/// </summary>
|
||||
/// <param name="timestamp">Временной интервал</param>
|
||||
/// <param name="checkedstamp">Проверяемый временной интервал</param>
|
||||
/// <param name="deltasec">Временная дельта в секундах</param>
|
||||
/// <returns>Попал ли <see cref="checkedstamp" /> в промежуток</returns>
|
||||
public static bool ValidateFromSec(long timestamp, long checkedstamp, ulong deltasec) =>
|
||||
Validate(timestamp, checkedstamp, checked(deltasec * 1000UL));
|
||||
|
||||
/// <summary>
|
||||
/// Проверка попадания текущего времени в заданный интервал (в сек)
|
||||
/// </summary>
|
||||
/// <param name="timestamp">Временной интервал</param>
|
||||
/// <param name="deltasec">Временная дельта в секундах</param>
|
||||
/// <returns>Попадает ли текущее время в промежуток <paramref name="timestamp" /> + <paramref name="deltasec" /></returns>
|
||||
public static bool ValidateFromSecNow(long timestamp, ulong deltasec) =>
|
||||
ValidateFromSec(timestamp, DateTime.UtcNow.Ticks, deltasec);
|
||||
|
||||
/// <summary>
|
||||
/// Проверка временного интервала (в мин)
|
||||
/// </summary>
|
||||
/// <param name="timestamp">Временной интервал</param>
|
||||
/// <param name="checkedstamp">Проверяемый временной интервал</param>
|
||||
/// <param name="deltamin">Временная дельта в минутах</param>
|
||||
/// <returns>
|
||||
/// Попал ли <see cref="checkedstamp" /> в промежуток <paramref name="timestamp" /> + <paramref name="deltamin" />
|
||||
/// </returns>
|
||||
public static bool ValidateFromMin(long timestamp, long checkedstamp, ulong deltamin) =>
|
||||
Validate(timestamp, checkedstamp, checked(deltamin * 60000UL));
|
||||
|
||||
/// <summary>
|
||||
/// Проверка попадания текущего времени в заданный интервал (в мин)
|
||||
/// </summary>
|
||||
/// <param name="timestamp">Временной интервал</param>
|
||||
/// <param name="deltamin">Временная дельта в минутах</param>
|
||||
/// <returns>Попадает ли текущее время в промежуток <paramref name="timestamp" /> + <paramref name="deltamin" /></returns>
|
||||
public static bool ValidateFromMinNow(long timestamp, ulong deltamin) =>
|
||||
ValidateFromMin(timestamp, DateTime.UtcNow.Ticks, deltamin);
|
||||
|
||||
/// <summary>
|
||||
/// Проверка временного интервала (в час)
|
||||
/// </summary>
|
||||
/// <param name="timestamp">Временной интервал</param>
|
||||
/// <param name="checkedstamp">Проверяемый временной интервал</param>
|
||||
/// <param name="deltahr">Временная дельта в часах</param>
|
||||
/// <returns>
|
||||
/// Попал ли <see cref="checkedstamp" /> в промежуток <paramref name="timestamp" /> + <paramref name="deltahr" />
|
||||
/// </returns>
|
||||
public static bool ValidateFromHour(long timestamp, long checkedstamp, ulong deltahr) =>
|
||||
Validate(timestamp, checkedstamp, checked(deltahr * 3600000UL));
|
||||
|
||||
/// <summary>
|
||||
/// Проверка попадания текущего времени в заданный интервал (в час)
|
||||
/// </summary>
|
||||
/// <param name="timestamp">Временной интервал</param>
|
||||
/// <param name="deltahr">Временная дельта в часах</param>
|
||||
/// <returns>Попадает ли текущее время в промежуток <paramref name="timestamp" /> + <paramref name="deltahr" /></returns>
|
||||
public static bool ValidateFromHourNow(long timestamp, ulong deltahr) =>
|
||||
ValidateFromHour(timestamp, DateTime.UtcNow.Ticks, deltahr);
|
||||
}
|
137
anbs_cp/Classes/TypeConverter.cs
Normal file
137
anbs_cp/Classes/TypeConverter.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
|
||||
namespace anbs_cp.Classes;
|
||||
|
||||
/// <summary>
|
||||
/// Конвертер типов на манер Delphi
|
||||
/// </summary>
|
||||
public static class TypeConverter
|
||||
{
|
||||
#region Конвертация числа в строку
|
||||
|
||||
/// <summary>
|
||||
/// Преобразование int в string
|
||||
/// </summary>
|
||||
/// <param name="AInt">Число</param>
|
||||
/// <returns>Строка</returns>
|
||||
public static string IntToStr(int AInt) => AInt.ToString();
|
||||
|
||||
/// <summary>
|
||||
/// Преобразование uint в string
|
||||
/// </summary>
|
||||
/// <param name="AInt">Число</param>
|
||||
/// <returns>Строка</returns>
|
||||
public static string IntToStr(uint AInt) => AInt.ToString();
|
||||
|
||||
/// <summary>
|
||||
/// Преобразование long в string
|
||||
/// </summary>
|
||||
/// <param name="AInt">Число</param>
|
||||
/// <returns>Строка</returns>
|
||||
public static string IntToStr(long AInt) => AInt.ToString();
|
||||
|
||||
/// <summary>
|
||||
/// Преобразование ulong в string
|
||||
/// </summary>
|
||||
/// <param name="AInt">Число</param>
|
||||
/// <returns>Строка</returns>
|
||||
public static string IntToStr(ulong AInt) => AInt.ToString();
|
||||
|
||||
/// <summary>
|
||||
/// Преобразование byte в string
|
||||
/// </summary>
|
||||
/// <param name="AInt">Число</param>
|
||||
/// <returns>Строка</returns>
|
||||
public static string IntToStr(byte AInt) => AInt.ToString();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Конвертация строки в число
|
||||
|
||||
/// <summary>
|
||||
/// Преобразование строки в число
|
||||
/// </summary>
|
||||
/// <param name="AStr">Строка</param>
|
||||
/// <param name="ADefault">Значение по умолчанию (по умолчанию, 0)</param>
|
||||
/// <returns>Число</returns>
|
||||
public static int StrToInt(string AStr, int ADefault = 0)
|
||||
{
|
||||
if (!int.TryParse(AStr, out int result)) result = ADefault;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Преобразование строки в число
|
||||
/// </summary>
|
||||
/// <param name="AStr">Строка</param>
|
||||
/// <param name="ADefault">Значение по умолчанию (по умолчанию, 0)</param>
|
||||
/// <returns>Число</returns>
|
||||
public static uint StrToUInt(string AStr, uint ADefault = 0)
|
||||
{
|
||||
if (!uint.TryParse(AStr, out uint result)) result = ADefault;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Преобразование строки в число
|
||||
/// </summary>
|
||||
/// <param name="AStr">Строка</param>
|
||||
/// <param name="ADefault">Значение по умолчанию (по умолчанию, 0)</param>
|
||||
/// <returns>Число</returns>
|
||||
public static long StrToInt64(string AStr, long ADefault = 0)
|
||||
{
|
||||
if (!long.TryParse(AStr, out long result)) result = ADefault;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Преобразование строки в число
|
||||
/// </summary>
|
||||
/// <param name="AStr">Строка</param>
|
||||
/// <param name="ADefault">Значение по умолчанию (по умолчанию, 0)</param>
|
||||
/// <returns>Число</returns>
|
||||
public static ulong StrToUInt64(string AStr, ulong ADefault = 0)
|
||||
{
|
||||
if (!ulong.TryParse(AStr, out ulong result)) result = ADefault;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Преобразование строки в число
|
||||
/// </summary>
|
||||
/// <param name="AStr">Строка</param>
|
||||
/// <param name="ADefault">Значение по умолчанию (по умолчанию, 0)</param>
|
||||
/// <returns>Число</returns>
|
||||
public static byte StrToByte(string AStr, byte ADefault = 0)
|
||||
{
|
||||
if (!byte.TryParse(AStr, out byte result)) result = ADefault;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Конвернтация IHtmlContent
|
||||
/// <summary>
|
||||
/// Преобразует тип <see cref="IHtmlContent"/> в строку <see cref="string"/>.
|
||||
/// </summary>
|
||||
/// <param name="content">Значение, которое нужно преобразовать.</param>
|
||||
/// <returns><see cref="string"/></returns>
|
||||
public static string HtmlContentToString(IHtmlContent content)
|
||||
{
|
||||
//Создаём writer
|
||||
using StringWriter writer = new();
|
||||
//Конвертируем IHtmlContent в string
|
||||
content.WriteTo(writer, HtmlEncoder.Default);
|
||||
//Возвращаем результат
|
||||
return writer.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Преобразует строку <see cref="string"/> в тип <see cref="IHtmlContent"/>.
|
||||
/// </summary>
|
||||
/// <param name="content">Значение, которое нужно преобразовать.</param>
|
||||
/// <returns><see cref="IHtmlContent"/></returns>
|
||||
public static IHtmlContent StringToHtmlContent(string content) => new HtmlContentBuilder().AppendHtml(content);
|
||||
#endregion
|
||||
}
|
Reference in New Issue
Block a user