package com.lemenzo.calculator.engine import java.math.BigDecimal object NumberInputParser { fun parse(raw: String, decimalSeparator: Char, groupingSeparator: Char): BigDecimal? { var value = raw.trim() .replace("\u00A0", "") .replace("\u202F", "") .replace(" ", "") if (value.isEmpty()) return null if (decimalSeparator == groupingSeparator) { return value.replace(decimalSeparator, '.').toBigDecimalOrNull() } if (value.contains(decimalSeparator)) { value = value.replace(groupingSeparator.toString(), "") value = value.replace(decimalSeparator, '.') return value.toBigDecimalOrNull() } if (value.contains(groupingSeparator)) { val count = value.count { it == groupingSeparator } if (count == 1) { val index = value.indexOf(groupingSeparator) val digitsAfter = value.length - index - 1 // Exactly three trailing digits is most likely locale grouping // (1,000 / 1.000). Other single-separator forms are accepted // as pasted decimal notation (1,5 / 1.5 / 1,25 / 1.2345). value = if (digitsAfter == 3 && value.substring(index + 1).all(Char::isDigit)) { value.removeRange(index, index + 1) } else { value.replace(groupingSeparator, '.') } } else { value = value.replace(groupingSeparator.toString(), "") } } return value.toBigDecimalOrNull() } }