Skip to content

Commit a756ee3

Browse files
authored
Merge pull request #3523 from Stranger6667/dd/expose-integer
feat(rust): add `Integer::to_u32_digits`
2 parents 854cd04 + 713f068 commit a756ee3

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

rust/ruby-prism/src/lib.rs

+40-1
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,24 @@ impl<'pr> Integer<'pr> {
250250
fn new(pointer: *const pm_integer_t) -> Self {
251251
Integer { pointer, marker: PhantomData }
252252
}
253+
254+
/// Returns the sign and the u32 digits representation of the integer,
255+
/// ordered least significant digit first.
256+
#[must_use]
257+
pub fn to_u32_digits(&self) -> (bool, &[u32]) {
258+
let negative = unsafe { (*self.pointer).negative };
259+
let length = unsafe { (*self.pointer).length };
260+
let values = unsafe { (*self.pointer).values };
261+
262+
if values.is_null() {
263+
let value_ptr = unsafe { std::ptr::addr_of!((*self.pointer).value) };
264+
let slice = unsafe { std::slice::from_raw_parts(value_ptr, 1) };
265+
(negative, slice)
266+
} else {
267+
let slice = unsafe { std::slice::from_raw_parts(values, length) };
268+
(negative, slice)
269+
}
270+
}
253271
}
254272

255273
impl std::fmt::Debug for Integer<'_> {
@@ -1144,11 +1162,32 @@ end
11441162
#[test]
11451163
fn integer_value_test() {
11461164
let result = parse("0xA".as_ref());
1147-
let value: i32 = result.node().as_program_node().unwrap().statements().body().iter().next().unwrap().as_integer_node().unwrap().value().try_into().unwrap();
1165+
let integer = result.node().as_program_node().unwrap().statements().body().iter().next().unwrap().as_integer_node().unwrap().value();
1166+
let value: i32 = integer.try_into().unwrap();
11481167

11491168
assert_eq!(value, 10);
11501169
}
11511170

1171+
#[test]
1172+
fn integer_small_value_to_u32_digits_test() {
1173+
let result = parse("0xA".as_ref());
1174+
let integer = result.node().as_program_node().unwrap().statements().body().iter().next().unwrap().as_integer_node().unwrap().value();
1175+
let (negative, digits) = integer.to_u32_digits();
1176+
1177+
assert!(!negative);
1178+
assert_eq!(digits, &[10]);
1179+
}
1180+
1181+
#[test]
1182+
fn integer_large_value_to_u32_digits_test() {
1183+
let result = parse("0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".as_ref());
1184+
let integer = result.node().as_program_node().unwrap().statements().body().iter().next().unwrap().as_integer_node().unwrap().value();
1185+
let (negative, digits) = integer.to_u32_digits();
1186+
1187+
assert!(!negative);
1188+
assert_eq!(digits, &[4_294_967_295, 4_294_967_295, 4_294_967_295, 2_147_483_647]);
1189+
}
1190+
11521191
#[test]
11531192
fn float_value_test() {
11541193
let result = parse("1.0".as_ref());

0 commit comments

Comments
 (0)