From 4eac1c55a2427d87cd13d164256c285fd0383250 Mon Sep 17 00:00:00 2001 From: nick evans Date: Wed, 19 Nov 2025 17:55:10 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=B7=EF=B8=8F=20Add=20`coerce=5F{type}`?= =?UTF-8?q?=20methods=20to=20NumValidator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/net/imap/data_encoding.rb | 41 +++++++++++++++++++++++ lib/net/imap/sequence_set.rb | 9 +---- test/net/imap/test_num_validator.rb | 52 +++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 8 deletions(-) diff --git a/lib/net/imap/data_encoding.rb b/lib/net/imap/data_encoding.rb index 90a4faf3..066272e6 100644 --- a/lib/net/imap/data_encoding.rb +++ b/lib/net/imap/data_encoding.rb @@ -155,6 +155,7 @@ def self.format_datetime(time) # Common validators of number and nz_number types module NumValidator # :nodoc + NUMBER_RE = /\A(?:0|[1-9]\d*)\z/ module_function # Check if argument is a valid 'number' according to RFC 3501 @@ -216,6 +217,46 @@ def ensure_mod_sequence_valzer(num) "mod-sequence-valzer must be unsigned 64-bit integer: #{num}" end + # Like #ensure_number, but usable with numeric String input. + def coerce_number(num) + case num + when Integer then ensure_number num + when NUMBER_RE then ensure_number Integer num + else + raise DataFormatError, "%p is not a valid number" % [num] + end + end + + # Like #ensure_nz_number, but usable with numeric String input. + def coerce_nz_number(num) + case num + when Integer then ensure_nz_number num + when NUMBER_RE then ensure_nz_number Integer num + else + raise DataFormatError, "%p is not a valid nz-number" % [num] + end + end + + # Like #ensure_mod_sequence_value, but usable with numeric String input. + def coerce_mod_sequence_value(num) + case num + when Integer then ensure_mod_sequence_value num + when NUMBER_RE then ensure_mod_sequence_value Integer num + else + raise DataFormatError, "%p is not a valid mod-sequence-value" % [num] + end + end + + # Like #ensure_mod_sequence_valzer, but usable with numeric String input. + def coerce_mod_sequence_valzer(num) + case num + when Integer then ensure_mod_sequence_valzer num + when NUMBER_RE then ensure_mod_sequence_valzer Integer num + else + raise DataFormatError, "%p is not a valid mod-sequence-valzer" % [num] + end + end + end end diff --git a/lib/net/imap/sequence_set.rb b/lib/net/imap/sequence_set.rb index 9491f2d3..d3078cfd 100644 --- a/lib/net/imap/sequence_set.rb +++ b/lib/net/imap/sequence_set.rb @@ -1921,14 +1921,7 @@ def import_range_minmax(range) end def import_num(obj) STARS.include?(obj) ? STAR_INT : nz_number(obj) end - - def nz_number(num) - String === num && !/\A[1-9]\d*\z/.match?(num) and - raise DataFormatError, "%p is not a valid nz-number" % [num] - NumValidator.ensure_nz_number Integer num - rescue TypeError # To catch errors from Integer() - raise DataFormatError, $!.message - end + def nz_number(num) = NumValidator.coerce_nz_number(num) ######################################################################{{{2 # Export methods diff --git a/test/net/imap/test_num_validator.rb b/test/net/imap/test_num_validator.rb index 6682faab..c07633f6 100644 --- a/test/net/imap/test_num_validator.rb +++ b/test/net/imap/test_num_validator.rb @@ -102,4 +102,56 @@ def assert_format_error end end + using_test_values_for :number do |label, value, valid| + result = valid ? "=> #{value}" : "raises DataFormatError" + [value, value.to_s].each do |input| + test "#coerce_number(%p) %s" % [input, result] do + if valid + assert_equal value, NumValidator.coerce_number(input) + else + assert_format_error do NumValidator.coerce_number(input) end + end + end + end + end + + using_test_values_for :"nz-number" do |label, value, valid| + result = valid ? "=> #{value}" : "raises DataFormatError" + [value, value.to_s].each do |input| + test "#coerce_nz_number(%p) %s" % [input, result] do + if valid + assert_equal value, NumValidator.coerce_nz_number(input) + else + assert_format_error do NumValidator.coerce_nz_number(input) end + end + end + end + end + + using_test_values_for :"mod-sequence-value" do |label, value, valid| + result = valid ? "=> #{value}" : "raises DataFormatError" + [value, value.to_s].each do |input| + test "#coerce_mod_sequence_value(%p) %s" % [input, result] do + if valid + assert_equal value, NumValidator.coerce_mod_sequence_value(input) + else + assert_format_error do NumValidator.coerce_mod_sequence_value(input) end + end + end + end + end + + using_test_values_for :"mod-sequence-valzer" do |label, value, valid| + result = valid ? "=> #{value}" : "raises DataFormatError" + [value, value.to_s].each do |input| + test "#coerce_mod_sequence_valzer(%p) %s" % [input, result] do + if valid + assert_equal value, NumValidator.coerce_mod_sequence_valzer(input) + else + assert_format_error do NumValidator.coerce_mod_sequence_valzer(input) end + end + end + end + end + end