Skip to content

Commit

Permalink
feat: add to_string to numbers (#19119)
Browse files Browse the repository at this point in the history
## Description 

Adds `to_string` to integer modules (`u8`->`u256`)

## Test plan 

Features tests.

---

## Release notes

* unsigned integers now support `.to_string()` methods, for example
`10u8.to_string()` is the same as `b"10".to_string()`

- [x] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [ ] JSON-RPC: 
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:
- [ ] REST API:
  • Loading branch information
thounyy authored and suiwombat committed Sep 16, 2024
1 parent 27fa488 commit b8dfbc0
Show file tree
Hide file tree
Showing 19 changed files with 309 additions and 122 deletions.
29 changes: 28 additions & 1 deletion crates/sui-framework/docs/move-stdlib/u128.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ title: Module `0x1::u128`
- [Function `divide_and_round_up`](#0x1_u128_divide_and_round_up)
- [Function `pow`](#0x1_u128_pow)
- [Function `sqrt`](#0x1_u128_sqrt)
- [Function `to_string`](#0x1_u128_to_string)


<pre><code></code></pre>
<pre><code><b>use</b> <a href="../move-stdlib/string.md#0x1_string">0x1::string</a>;
<b>use</b> <a href="../move-stdlib/vector.md#0x1_vector">0x1::vector</a>;
</code></pre>



Expand Down Expand Up @@ -188,4 +191,28 @@ math::sqrt(8 * 1000000) => 2828; // same as above, 2828 / 1000 (2.828)



</details>

<a name="0x1_u128_to_string"></a>

## Function `to_string`



<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_to_string">to_string</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): <a href="../move-stdlib/string.md#0x1_string_String">string::String</a>
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_to_string">to_string</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): String {
std::macros::num_to_string!(x)
}
</code></pre>



</details>
29 changes: 28 additions & 1 deletion crates/sui-framework/docs/move-stdlib/u64.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ title: Module `0x1::u64`
- [Function `divide_and_round_up`](#0x1_u64_divide_and_round_up)
- [Function `pow`](#0x1_u64_pow)
- [Function `sqrt`](#0x1_u64_sqrt)
- [Function `to_string`](#0x1_u64_to_string)


<pre><code></code></pre>
<pre><code><b>use</b> <a href="../move-stdlib/string.md#0x1_string">0x1::string</a>;
<b>use</b> <a href="../move-stdlib/vector.md#0x1_vector">0x1::vector</a>;
</code></pre>



Expand Down Expand Up @@ -188,4 +191,28 @@ math::sqrt(8 * 1000000) => 2828; // same as above, 2828 / 1000 (2.828)



</details>

<a name="0x1_u64_to_string"></a>

## Function `to_string`



<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u64.md#0x1_u64_to_string">to_string</a>(x: <a href="../move-stdlib/u64.md#0x1_u64">u64</a>): <a href="../move-stdlib/string.md#0x1_string_String">string::String</a>
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u64.md#0x1_u64_to_string">to_string</a>(x: <a href="../move-stdlib/u64.md#0x1_u64">u64</a>): String {
std::macros::num_to_string!(x)
}
</code></pre>



</details>
16 changes: 16 additions & 0 deletions crates/sui-framework/packages/move-stdlib/sources/macros.move
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

/// This module holds shared implementation of macros used in `std`
module std::macros {
use std::string::String;

public macro fun num_max($x: _, $y: _): _ {
let x = $x;
let y = $y;
Expand Down Expand Up @@ -68,6 +70,20 @@ module std::macros {
res as $T
}

public macro fun num_to_string($x: _): String {
let mut x = $x;
if (x == 0) {
return b"0".to_string()
};
let mut buffer = vector[];
while (x != 0) {
buffer.push_back(((48 + x % 10) as u8));
x = x / 10;
};
buffer.reverse();
buffer.to_string()
}

public macro fun range_do($start: _, $stop: _, $f: |_|) {
let mut i = $start;
let stop = $stop;
Expand Down
6 changes: 6 additions & 0 deletions crates/sui-framework/packages/move-stdlib/sources/u128.move
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#[defines_primitive(u128)]
module std::u128 {
use std::string::String;

/// Return the larger of `x` and `y`
public fun max(x: u128, y: u128): u128 {
std::macros::num_max!(x, y)
Expand Down Expand Up @@ -57,6 +59,10 @@ module std::u128 {
std::macros::num_sqrt!<u128, u256>(x, 128)
}

public fun to_string(x: u128): String {
std::macros::num_to_string!(x)
}

/// Loops applying `$f` to each number from `$start` to `$stop` (exclusive)
public macro fun range_do($start: u128, $stop: u128, $f: |u128|) {
std::macros::range_do!($start, $stop, $f)
Expand Down
6 changes: 6 additions & 0 deletions crates/sui-framework/packages/move-stdlib/sources/u16.move
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#[defines_primitive(u16)]
module std::u16 {
use std::string::String;

/// Return the larger of `x` and `y`
public fun max(x: u16, y: u16): u16 {
std::macros::num_max!(x, y)
Expand Down Expand Up @@ -57,6 +59,10 @@ module std::u16 {
std::macros::num_sqrt!<u16, u32>(x, 16)
}

public fun to_string(x: u16): String {
std::macros::num_to_string!(x)
}

/// Loops applying `$f` to each number from `$start` to `$stop` (exclusive)
public macro fun range_do($start: u16, $stop: u16, $f: |u16|) {
std::macros::range_do!($start, $stop, $f)
Expand Down
6 changes: 6 additions & 0 deletions crates/sui-framework/packages/move-stdlib/sources/u256.move
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#[defines_primitive(u256)]
module std::u256 {
use std::string::String;

/// Return the larger of `x` and `y`
public fun max(x: u256, y: u256): u256 {
std::macros::num_max!(x, y)
Expand All @@ -28,6 +30,10 @@ module std::u256 {
std::macros::num_pow!(base, exponent)
}

public fun to_string(x: u256): String {
std::macros::num_to_string!(x)
}

/// Loops applying `$f` to each number from `$start` to `$stop` (exclusive)
public macro fun range_do($start: u256, $stop: u256, $f: |u256|) {
std::macros::range_do!($start, $stop, $f)
Expand Down
6 changes: 6 additions & 0 deletions crates/sui-framework/packages/move-stdlib/sources/u32.move
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#[defines_primitive(u32)]
module std::u32 {
use std::string::String;

/// Return the larger of `x` and `y`
public fun max(x: u32, y: u32): u32 {
std::macros::num_max!(x, y)
Expand Down Expand Up @@ -57,6 +59,10 @@ module std::u32 {
std::macros::num_sqrt!<u32, u64>(x, 32)
}

public fun to_string(x: u32): String {
std::macros::num_to_string!(x)
}

/// Loops applying `$f` to each number from `$start` to `$stop` (exclusive)
public macro fun range_do($start: u32, $stop: u32, $f: |u32|) {
std::macros::range_do!($start, $stop, $f)
Expand Down
6 changes: 6 additions & 0 deletions crates/sui-framework/packages/move-stdlib/sources/u64.move
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#[defines_primitive(u64)]
module std::u64 {
use std::string::String;

/// Return the larger of `x` and `y`
public fun max(x: u64, y: u64): u64 {
std::macros::num_max!(x, y)
Expand Down Expand Up @@ -57,6 +59,10 @@ module std::u64 {
std::macros::num_sqrt!<u64, u128>(x, 64)
}

public fun to_string(x: u64): String {
std::macros::num_to_string!(x)
}

/// Loops applying `$f` to each number from `$start` to `$stop` (exclusive)
public macro fun range_do($start: u64, $stop: u64, $f: |u64|) {
std::macros::range_do!($start, $stop, $f)
Expand Down
6 changes: 6 additions & 0 deletions crates/sui-framework/packages/move-stdlib/sources/u8.move
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#[defines_primitive(u8)]
module std::u8 {
use std::string::String;

/// Return the larger of `x` and `y`
public fun max(x: u8, y: u8): u8 {
std::macros::num_max!(x, y)
Expand Down Expand Up @@ -57,6 +59,10 @@ module std::u8 {
std::macros::num_sqrt!<u8, u16>(x, 8)
}

public fun to_string(x: u8): String {
std::macros::num_to_string!(x)
}

/// Loops applying `$f` to each number from `$start` to `$stop` (exclusive)
public macro fun range_do($start: u8, $stop: u8, $f: |u8|) {
std::macros::range_do!($start, $stop, $f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,15 @@ module std::integer_tests {
(n * (n + 1)) / 2
}

public(package) macro fun test_to_string<$T>() {
assert_eq!((0: $T).to_string(), b"0".to_string());
assert_eq!((1: $T).to_string(), b"1".to_string());
assert_eq!((10: $T).to_string(), b"10".to_string());
assert_eq!((11: $T).to_string(), b"11".to_string());
assert_eq!((100: $T).to_string(), b"100".to_string());
assert_eq!((111: $T).to_string(), b"111".to_string());
}

public(package) macro fun test_dos_case<$T>($case: $T) {
let case = $case;
let mut sum: $T = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ module std::u128_tests {
integer_tests::test_sqrt!(MAX, CASES, reflexive_cases)
}

#[test]
fun test_to_string() {
integer_tests::test_to_string!<u128>();
assert_eq!((MAX / 2).to_string(), b"170141183460469231731687303715884105727".to_string());
assert_eq!((MAX / 2 + 1).to_string(), b"170141183460469231731687303715884105728".to_string());
assert_eq!(MAX_PRED.to_string(), b"340282366920938463463374607431768211454".to_string());
assert_eq!(MAX.to_string(), b"340282366920938463463374607431768211455".to_string());
}

#[test]
fun test_dos() {
integer_tests::test_dos!(MAX, CASES);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ module std::u16_tests {
integer_tests::test_sqrt!(MAX, CASES, reflexive_cases)
}

#[test]
fun test_to_string() {
integer_tests::test_to_string!<u16>();
assert_eq!((MAX / 2).to_string(), b"32767".to_string());
assert_eq!((MAX / 2 + 1).to_string(), b"32768".to_string());
assert_eq!(MAX_PRED.to_string(), b"65534".to_string());
assert_eq!(MAX.to_string(), b"65535".to_string());
}

#[test]
fun test_dos() {
integer_tests::test_dos!(MAX, CASES);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ module std::u256_tests {
255u256.pow(255);
}

#[test]
fun test_to_string() {
integer_tests::test_to_string!<u256>();
assert_eq!((MAX / 2).to_string(), b"57896044618658097711785492504343953926634992332820282019728792003956564819967".to_string());
assert_eq!((MAX / 2 + 1).to_string(), b"57896044618658097711785492504343953926634992332820282019728792003956564819968".to_string());
assert_eq!(MAX_PRED.to_string(), b"115792089237316195423570985008687907853269984665640564039457584007913129639934".to_string());
assert_eq!(MAX.to_string(), b"115792089237316195423570985008687907853269984665640564039457584007913129639935".to_string());
}

#[test]
fun test_dos() {
integer_tests::test_dos!(MAX, CASES);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ module std::u32_tests {
integer_tests::test_sqrt!(MAX, CASES, reflexive_cases)
}

#[test]
fun test_to_string() {
integer_tests::test_to_string!<u32>();
assert_eq!((MAX / 2).to_string(), b"2147483647".to_string());
assert_eq!((MAX / 2 + 1).to_string(), b"2147483648".to_string());
assert_eq!(MAX_PRED.to_string(), b"4294967294".to_string());
assert_eq!(MAX.to_string(), b"4294967295".to_string());
}

#[test]
fun test_dos() {
integer_tests::test_dos!(MAX, CASES);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ module std::u64_tests {
integer_tests::test_sqrt!(MAX, CASES, reflexive_cases)
}

#[test]
fun test_to_string() {
integer_tests::test_to_string!<u64>();
assert_eq!((MAX / 2).to_string(), b"9223372036854775807".to_string());
assert_eq!((MAX / 2 + 1).to_string(), b"9223372036854775808".to_string());
assert_eq!(MAX_PRED.to_string(), b"18446744073709551614".to_string());
assert_eq!(MAX.to_string(), b"18446744073709551615".to_string());
}

#[test]
fun test_dos() {
integer_tests::test_dos!(MAX, CASES);
Expand Down
9 changes: 9 additions & 0 deletions crates/sui-framework/packages/move-stdlib/tests/u8_tests.move
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ module std::u8_tests {
integer_tests::test_sqrt!(MAX, CASES, vector[0, 2, 5, 8, 11, 14]);
}

#[test]
fun test_to_string() {
integer_tests::test_to_string!<u8>();
assert_eq!((MAX / 2).to_string(), b"127".to_string());
assert_eq!((MAX / 2 + 1).to_string(), b"128".to_string());
assert_eq!(MAX_PRED.to_string(), b"254".to_string());
assert_eq!(MAX.to_string(), b"255".to_string());
}

#[test]
fun test_dos() {
let mut sum = 0u16;
Expand Down
Binary file modified crates/sui-framework/packages_compiled/move-stdlib
Binary file not shown.
Loading

0 comments on commit b8dfbc0

Please sign in to comment.