From 78bfd2b5fccf320e5aec0438a0c2fefbb2cb6c65 Mon Sep 17 00:00:00 2001 From: Svjatoslav Agejenko Date: Thu, 20 Mar 2025 23:39:26 +0200 Subject: [PATCH] Better bounds checking --- .../commons/cli_helper/CLIHelper.java | 120 +++++++++++++----- 1 file changed, 90 insertions(+), 30 deletions(-) diff --git a/src/main/java/eu/svjatoslav/commons/cli_helper/CLIHelper.java b/src/main/java/eu/svjatoslav/commons/cli_helper/CLIHelper.java index 16e5aa2..7866fc6 100755 --- a/src/main/java/eu/svjatoslav/commons/cli_helper/CLIHelper.java +++ b/src/main/java/eu/svjatoslav/commons/cli_helper/CLIHelper.java @@ -6,10 +6,6 @@ package eu.svjatoslav.commons.cli_helper; import java.util.Scanner; -import static java.lang.Float.parseFloat; -import static java.lang.Long.parseLong; -import static java.lang.String.valueOf; - /** * Command-line interface helper. */ @@ -62,24 +58,56 @@ public class CLIHelper { /** * Asks the user for a float value using the specified prompt on the command line. - * The user is prompted until a valid float within the specified range [min..max] is provided. - * An empty input (just pressing ENTER) will use the provided defaultValue. + * The user is prompted until a valid float (within optional ranges) is provided. + * * - * @param prompt the message to display to the user - * @param defaultValue the float value to use if the user provides no input - * @param min the minimum acceptable value (inclusive) - * @param max the maximum acceptable value (inclusive) - * @return a float value entered by the user, or {@code defaultValue} if empty input + * @param prompt The prompt displayed to the user + * @param defaultValue The default float if user simply presses Enter (may be null) + * @param min The minimum acceptable value (inclusive), or null if no lower bound + * @param max The maximum acceptable value (inclusive), or null if no upper bound + * @return A Float value that the user entered, or the defaultValue, or null if no defaultValue was given */ - public float askFloat(String prompt, float defaultValue, float min, float max) { + public Float askFloat(String prompt, Float defaultValue, Float min, Float max) { while (true) { - String input = askString(prompt, valueOf(defaultValue)); + // If we have a defaultValue, display it in brackets; otherwise display no default + String displayPrompt = prompt + + (defaultValue != null ? " [" + defaultValue + "]" : "") + + ": "; + + // Read user input + System.out.print(displayPrompt); + String input = new Scanner(System.in).nextLine().trim(); + + // If user just pressed Enter: + if (input.isEmpty()) { + // If a defaultValue was supplied, return it; else return null + return defaultValue; + } + + // Parse float value try { - float parsedValue = parseFloat(input); - if (parsedValue >= min && parsedValue <= max) { - return parsedValue; + float parsedValue = Float.parseFloat(input); + + // Check against min if specified + if (min != null && parsedValue < min) { + System.out.println("Value must be at least " + min + "."); + continue; } - System.out.println("Value must be between " + min + " and " + max + "."); + + // Check against max if specified + if (max != null && parsedValue > max) { + System.out.println("Value must be at most " + max + "."); + continue; + } + + // Parsed successfully within optional bounds + return parsedValue; + } catch (NumberFormatException e) { System.out.println("Invalid number format. Try again."); } @@ -88,24 +116,56 @@ public class CLIHelper { /** * Asks the user for a long value using the specified prompt on the command line. - * The user is prompted until a valid long within the specified range [min..max] is provided. - * An empty input (just pressing ENTER) will use the provided defaultValue. + * The user is prompted until a valid long (within optional ranges) is provided. + * * - * @param prompt the message to display to the user - * @param defaultValue the long value to use if the user provides no input - * @param min the minimum acceptable value (inclusive) - * @param max the maximum acceptable value (inclusive) - * @return a long value entered by the user, or {@code defaultValue} if empty input + * @param prompt The prompt displayed to the user + * @param defaultValue The default long if user simply presses Enter (may be null) + * @param min The minimum acceptable value (inclusive), or null if no lower bound + * @param max The maximum acceptable value (inclusive), or null if no upper bound + * @return A Long value that the user entered, or the defaultValue, or null if no defaultValue was given */ - public long askLong(String prompt, long defaultValue, long min, long max) { + public Long askLong(String prompt, Long defaultValue, Long min, Long max) { while (true) { - String input = askString(prompt, valueOf(defaultValue)); + // If we have a defaultValue, display it in brackets; otherwise display no default + String displayPrompt = prompt + + (defaultValue != null ? " [" + defaultValue + "]" : "") + + ": "; + + // Read user input + System.out.print(displayPrompt); + String input = new Scanner(System.in).nextLine().trim(); + + // If user just pressed Enter: + if (input.isEmpty()) { + // If a defaultValue was supplied, return it; else return null + return defaultValue; + } + + // Parse long value try { - long parsedValue = parseLong(input); - if (parsedValue >= min && parsedValue <= max) { - return parsedValue; + long parsedValue = Long.parseLong(input); + + // Check against min if specified + if (min != null && parsedValue < min) { + System.out.println("Value must be at least " + min + "."); + continue; + } + + // Check against max if specified + if (max != null && parsedValue > max) { + System.out.println("Value must be at most " + max + "."); + continue; } - System.out.println("Value must be between " + min + " and " + max + "."); + + // Parsed successfully within optional bounds + return parsedValue; + } catch (NumberFormatException e) { System.out.println("Invalid number format. Try again."); } -- 2.20.1