mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-22 00:54:26 +08:00
124 lines
3.0 KiB
C#
124 lines
3.0 KiB
C#
using System;
|
|
using System.Globalization;
|
|
|
|
namespace LanMountainDesktop.Services;
|
|
|
|
public sealed class CalculatorDataService : ICalculatorDataService
|
|
{
|
|
private const int MaxInputLength = 18;
|
|
|
|
public string ApplyInputToken(string currentInput, string token)
|
|
{
|
|
var normalized = NormalizeInput(currentInput);
|
|
if (string.IsNullOrWhiteSpace(token))
|
|
{
|
|
return normalized;
|
|
}
|
|
|
|
if (string.Equals(token, CalculatorInputTokens.Clear, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return "0";
|
|
}
|
|
|
|
if (string.Equals(token, CalculatorInputTokens.Backspace, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
if (normalized.Length <= 1)
|
|
{
|
|
return "0";
|
|
}
|
|
|
|
var trimmed = normalized[..^1];
|
|
if (trimmed is "-" or "" or "-0")
|
|
{
|
|
return "0";
|
|
}
|
|
|
|
return trimmed;
|
|
}
|
|
|
|
if (string.Equals(token, CalculatorInputTokens.DecimalPoint, StringComparison.Ordinal))
|
|
{
|
|
if (normalized.Contains('.', StringComparison.Ordinal))
|
|
{
|
|
return normalized;
|
|
}
|
|
|
|
if (normalized.Length >= MaxInputLength)
|
|
{
|
|
return normalized;
|
|
}
|
|
|
|
return $"{normalized}.";
|
|
}
|
|
|
|
if (token is "00")
|
|
{
|
|
if (normalized == "0")
|
|
{
|
|
return "0";
|
|
}
|
|
|
|
if (normalized.Length + 2 > MaxInputLength)
|
|
{
|
|
return normalized;
|
|
}
|
|
|
|
return normalized + "00";
|
|
}
|
|
|
|
if (token.Length == 1 && char.IsDigit(token[0]))
|
|
{
|
|
if (normalized == "0")
|
|
{
|
|
return token;
|
|
}
|
|
|
|
if (normalized.Length >= MaxInputLength)
|
|
{
|
|
return normalized;
|
|
}
|
|
|
|
return normalized + token;
|
|
}
|
|
|
|
return normalized;
|
|
}
|
|
|
|
public decimal ParseAmountOrZero(string? inputText)
|
|
{
|
|
var normalized = NormalizeInput(inputText);
|
|
if (decimal.TryParse(
|
|
normalized,
|
|
NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint,
|
|
CultureInfo.InvariantCulture,
|
|
out var amount))
|
|
{
|
|
return amount;
|
|
}
|
|
|
|
return 0m;
|
|
}
|
|
|
|
public string FormatAmount(decimal amount, int maxFractionDigits = 4)
|
|
{
|
|
var safeDigits = Math.Clamp(maxFractionDigits, 0, 8);
|
|
var pattern = safeDigits == 0 ? "0" : $"0.{new string('#', safeDigits)}";
|
|
return amount.ToString(pattern, CultureInfo.InvariantCulture);
|
|
}
|
|
|
|
private static string NormalizeInput(string? input)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(input))
|
|
{
|
|
return "0";
|
|
}
|
|
|
|
var trimmed = input.Trim();
|
|
return trimmed switch
|
|
{
|
|
"-" or "-0" => "0",
|
|
_ => trimmed
|
|
};
|
|
}
|
|
}
|