Fix number formatter following removal of Fixnum / Bignum from ruby-next (#50)

The current ruby head in CI removes Fixnum and Bignum classes, which has led to broken builds.

This fix attempts to coalesce the passed-in number to an `int64_t`; if that fails, it falls back to calling `unum_format_decimal` - if the versions of ICU does not support `unum_format_decimal`, a `RangeError` will be raised (which should not be an issue for modern versions of ICU)
This commit is contained in:
Konstantinos Tsanaktsidis 2022-03-16 12:15:44 +11:00 committed by GitHub
parent 0c6f8b201f
commit d2241ad65f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 4 deletions

View File

@ -68,8 +68,19 @@ module ICU
case number
when Float
needed_length = Lib.unum_format_double(@f, number, out_ptr, needed_length, nil, error)
when Fixnum
needed_length = Lib.unum_format_int32(@f, number, out_ptr, needed_length, nil, error)
when Integer
begin
# Try doing it fast, for integers that can be marshaled into an int64_t
needed_length = Lib.unum_format_int64(@f, number, out_ptr, needed_length, nil, error)
rescue RangeError
# Fall back to stringifying in Ruby and passing that to ICU
unless defined? Lib.unum_format_decimal
raise RangeError,"Number #{number} is too big to fit in int64_t and your "\
"ICU version is too old to have unum_format_decimal"
end
string_version = number.to_s
needed_length = Lib.unum_format_decimal(@f, string_version, string_version.bytesize, out_ptr, needed_length, nil, error)
end
when BigDecimal
string_version = number.to_s('F')
if Lib.respond_to? :unum_format_decimal
@ -77,8 +88,6 @@ module ICU
else
needed_length = Lib.unum_format_double(@f, number.to_f, out_ptr, needed_length, nil, error)
end
when Bignum
needed_length = Lib.unum_format_int64(@f, number, out_ptr, needed_length, nil, error)
end
end
out_ptr.string needed_length

View File

@ -69,6 +69,11 @@ module ICU
expect { NumberFormatting.create('en-US', :currency, style: :iso) }.to raise_error(StandardError)
end
end
it 'should format a bignum' do
str = NumberFormatting.format_number("en", 1_000_000_000_000_000_000_000_000_000_000_000_000_000)
expect(str).to eq('1,000,000,000,000,000,000,000,000,000,000,000,000,000')
end
end
end # NumberFormatting
end # ICU