Skip to content

Commit 1194375

Browse files
authored
Add resize() to Vec and Bytes (#6864)
## Description There exists no `resize()` functionality for `Vec` and `Bytes`. This has been implemented in this PR and mimics Rust's behavior. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [x] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
1 parent d48a793 commit 1194375

File tree

14 files changed

+471
-95
lines changed

14 files changed

+471
-95
lines changed

sway-lib-std/src/bytes.sw

+55
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,61 @@ impl Bytes {
816816

817817
spliced
818818
}
819+
820+
/// Resizes the `Bytes` in-place so that `len` is equal to `new_len`.
821+
///
822+
/// # Additional Information
823+
///
824+
/// If `new_len` is greater than `len`, the `Bytes` is extended by the difference, with each additional slot filled with `value`. If `new_len` is less than `len`, the `Bytes` is simply truncated.
825+
///
826+
/// # Arguments
827+
///
828+
/// * `new_len`: [u64] - The new length of the `Bytes`.
829+
/// * `value`: [u8] - The value to fill the new length.
830+
///
831+
/// # Examples
832+
///
833+
/// ```sway
834+
/// fn foo() {
835+
/// let bytes = Bytes::new();
836+
/// bytes.resize(1, 7u8);
837+
/// assert(bytes.len() == 1);
838+
/// assert(bytes.get(0).unwrap() == 7u8);
839+
///
840+
/// bytes.resize(2, 9u8);
841+
/// assert(bytes.len() == 2);
842+
/// assert(bytes.get(0).unwrap() == 7u8);
843+
/// assert(bytes.get(1).unwrap() == 9u8);
844+
///
845+
/// bytes.resize(1, 0);
846+
/// assert(bytes.len() == 1);
847+
/// assert(bytes.get(0).unwrap() == 7u8);
848+
/// assert(bytes.get(1) == None);
849+
/// }
850+
/// ```
851+
pub fn resize(ref mut self, new_len: u64, value: u8) {
852+
// If the `new_len` is less then truncate
853+
if self.len >= new_len {
854+
self.len = new_len;
855+
return;
856+
}
857+
858+
// If we don't have enough capacity, alloc more
859+
if self.buf.cap < new_len {
860+
self.buf.ptr = realloc_bytes(self.buf.ptr, self.buf.cap, new_len);
861+
self.buf.cap = new_len;
862+
}
863+
864+
// Fill the new length with value
865+
let mut i = 0;
866+
let start_ptr = self.buf.ptr.add_uint_offset(self.len);
867+
while i + self.len < new_len {
868+
start_ptr.add_uint_offset(i).write_byte(value);
869+
i += 1;
870+
}
871+
872+
self.len = new_len;
873+
}
819874
}
820875

821876
impl core::ops::Eq for Bytes {

sway-lib-std/src/vec.sw

+55
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,61 @@ impl<T> Vec<T> {
698698
pub fn ptr(self) -> raw_ptr {
699699
self.buf.ptr()
700700
}
701+
702+
/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
703+
///
704+
/// # Additional Information
705+
///
706+
/// If `new_len` is greater than `len`, the `Vec` is extended by the difference, with each additional slot filled with `value`. If `new_len` is less than `len`, the `Vec` is simply truncated.
707+
///
708+
/// # Arguments
709+
///
710+
/// * `new_len`: [u64] - The new length of the `Vec`.
711+
/// * `value`: [T] - The value to fill the new length.
712+
///
713+
/// # Examples
714+
///
715+
/// ```sway
716+
/// fn foo() {
717+
/// let vec: Vec<u64> = Vec::new();
718+
/// vec.resize(1, 7);
719+
/// assert(vec.len() == 1);
720+
/// assert(vec.get(0).unwrap() == 7);
721+
///
722+
/// vec.resize(2, 9);
723+
/// assert(vec.len() == 2);
724+
/// assert(vec.get(0).unwrap() == 7);
725+
/// assert(vec.get(1).unwrap() == 9);
726+
///
727+
/// vec.resize(1, 0);
728+
/// assert(vec.len() == 1);
729+
/// assert(vec.get(0).unwrap() == 7);
730+
/// assert(vec.get(1) == None);
731+
/// }
732+
/// ```
733+
pub fn resize(ref mut self, new_len: u64, value: T) {
734+
// If the `new_len` is less then truncate
735+
if self.len >= new_len {
736+
self.len = new_len;
737+
return;
738+
}
739+
740+
// If we don't have enough capacity, alloc more
741+
if self.buf.cap < new_len {
742+
self.buf.ptr = realloc::<T>(self.buf.ptr, self.buf.cap, new_len);
743+
self.buf.cap = new_len;
744+
}
745+
746+
// Fill the new length with `value`
747+
let mut i = 0;
748+
let start_ptr = self.buf.ptr.add::<T>(self.len);
749+
while i + self.len < new_len {
750+
start_ptr.add::<T>(i).write::<T>(value);
751+
i += 1;
752+
}
753+
754+
self.len = new_len;
755+
}
701756
}
702757

703758
impl<T> AsRawSlice for Vec<T> {

test/src/in_language_tests/test_programs/b512_inline_tests/src/main.sw

+4-1
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,10 @@ fn b512_into_bytes() {
352352
iter_2 += 1;
353353
}
354354

355-
let b512_3 = B512::from((b256::zero() , 0x0000000000000000000000000000000000000000000000000000000000000001));
355+
let b512_3 = B512::from((
356+
b256::zero(),
357+
0x0000000000000000000000000000000000000000000000000000000000000001,
358+
));
356359
let bytes_3: Bytes = <B512 as Into<Bytes>>::into(b512_3);
357360
assert(bytes_3.capacity() == 64);
358361
assert(bytes_3.len() == 64);

test/src/in_language_tests/test_programs/bytes_inline_tests/src/main.sw

+64
Original file line numberDiff line numberDiff line change
@@ -1132,3 +1132,67 @@ fn bytes_test_u8_limits() {
11321132
assert(bytes.get(4).unwrap() == max);
11331133
assert(bytes.get(5).unwrap() == min);
11341134
}
1135+
1136+
#[test]
1137+
fn bytes_resize() {
1138+
let (mut bytes_1, a, b, c) = setup();
1139+
assert(bytes_1.len() == 3);
1140+
assert(bytes_1.capacity() == 4);
1141+
1142+
// Resize to same size, no effect
1143+
bytes_1.resize(3, 0);
1144+
assert(bytes_1.len() == 3);
1145+
assert(bytes_1.capacity() == 4);
1146+
1147+
// Resize to capacity size doesn't impact capacity
1148+
bytes_1.resize(4, 1);
1149+
assert(bytes_1.len() == 4);
1150+
assert(bytes_1.capacity() == 4);
1151+
assert(bytes_1.get(0) == Some(5));
1152+
assert(bytes_1.get(1) == Some(7));
1153+
assert(bytes_1.get(2) == Some(9));
1154+
assert(bytes_1.get(3) == Some(1));
1155+
1156+
// Resize increases size and capacity
1157+
bytes_1.resize(10, 2);
1158+
assert(bytes_1.len() == 10);
1159+
assert(bytes_1.capacity() == 10);
1160+
assert(bytes_1.get(0) == Some(5));
1161+
assert(bytes_1.get(1) == Some(7));
1162+
assert(bytes_1.get(2) == Some(9));
1163+
assert(bytes_1.get(3) == Some(1));
1164+
assert(bytes_1.get(4) == Some(2));
1165+
assert(bytes_1.get(5) == Some(2));
1166+
assert(bytes_1.get(6) == Some(2));
1167+
assert(bytes_1.get(7) == Some(2));
1168+
assert(bytes_1.get(8) == Some(2));
1169+
assert(bytes_1.get(9) == Some(2));
1170+
1171+
// Resize to less doesn't impact capacity or order
1172+
bytes_1.resize(1, 0);
1173+
assert(bytes_1.len() == 1);
1174+
assert(bytes_1.capacity() == 10);
1175+
assert(bytes_1.get(0) == Some(5));
1176+
assert(bytes_1.get(1) == None);
1177+
1178+
// Resize to zero doesn't impact capacity and returns None
1179+
bytes_1.resize(0, 0);
1180+
assert(bytes_1.len() == 0);
1181+
assert(bytes_1.capacity() == 10);
1182+
assert(bytes_1.get(0) == None);
1183+
1184+
let mut bytes_2 = Bytes::new();
1185+
1186+
// Resize to zero on empty vec doesn't impact
1187+
bytes_2.resize(0, 0);
1188+
assert(bytes_2.len() == 0);
1189+
assert(bytes_2.capacity() == 0);
1190+
1191+
// Resize on empty vec fills and sets capacity
1192+
bytes_2.resize(3, 1);
1193+
assert(bytes_2.len() == 3);
1194+
assert(bytes_2.capacity() == 3);
1195+
assert(bytes_2.get(0) == Some(1));
1196+
assert(bytes_2.get(1) == Some(1));
1197+
assert(bytes_2.get(2) == Some(1));
1198+
}

test/src/in_language_tests/test_programs/crypto_ed25519_inline_tests/src/main.sw

+69-29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
library;
22

3-
use std::{bytes::Bytes, b512::B512, crypto::{ed25519::*, public_key::*, message::*}, hash::{Hash, sha256}, vm::evm::evm_address::EvmAddress};
3+
use std::{
4+
b512::B512,
5+
bytes::Bytes,
6+
crypto::{
7+
ed25519::*,
8+
message::*,
9+
public_key::*,
10+
},
11+
hash::{
12+
Hash,
13+
sha256,
14+
},
15+
vm::evm::evm_address::EvmAddress,
16+
};
417

518
#[test]
619
fn ed25519_new() {
@@ -74,7 +87,10 @@ fn ed25519_from_b512() {
7487
iter_1 += 1;
7588
}
7689

77-
let b512_2 = B512::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
90+
let b512_2 = B512::from((
91+
b256::zero(),
92+
0x0000000000000000000000000000000000000000000000000000000000000001,
93+
));
7894
let ed25519_2 = Ed25519::from(b512_2);
7995
assert(ed25519_2.bits()[63] == 1u8);
8096
let mut iter_2 = 0;
@@ -101,7 +117,10 @@ fn ed25519_from_b256_tuple() {
101117
iter_1 += 1;
102118
}
103119

104-
let ed25519_2 = Ed25519::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
120+
let ed25519_2 = Ed25519::from((
121+
b256::zero(),
122+
0x0000000000000000000000000000000000000000000000000000000000000001,
123+
));
105124
assert(ed25519_2.bits()[63] == 1u8);
106125
let mut iter_2 = 0;
107126
while iter_2 < 63 {
@@ -120,12 +139,12 @@ fn ed25519_from_b256_tuple() {
120139
#[test]
121140
fn ed25519_from_u8_array() {
122141
let array_1 = [
123-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
124-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
125-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
126-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
127-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
128-
];
142+
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
143+
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
144+
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
145+
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
146+
0u8, 0u8, 0u8, 0u8,
147+
];
129148
let ed25519_1 = Ed25519::from(array_1);
130149
let mut iter_1 = 0;
131150
while iter_1 < 64 {
@@ -134,12 +153,12 @@ fn ed25519_from_u8_array() {
134153
}
135154

136155
let array_2 = [
137-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
138-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
139-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
140-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
141-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
142-
];
156+
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
157+
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
158+
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
159+
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
160+
0u8, 0u8, 0u8, 1u8,
161+
];
143162
let ed25519_2 = Ed25519::from(array_2);
144163
assert(ed25519_2.bits()[63] == 1u8);
145164
let mut iter_2 = 0;
@@ -149,12 +168,13 @@ fn ed25519_from_u8_array() {
149168
}
150169

151170
let array_3 = [
152-
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
153-
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
154-
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
155-
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
156-
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
157-
];
171+
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
172+
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
173+
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
174+
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
175+
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
176+
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
177+
];
158178
let ed25519_3 = Ed25519::from(array_3);
159179
let mut iter_3 = 0;
160180
while iter_3 < 64 {
@@ -174,7 +194,10 @@ fn ed25519_try_from_bytes() {
174194
iter_1 += 1;
175195
}
176196

177-
let b256_tuple_2 = (b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001);
197+
let b256_tuple_2 = (
198+
b256::zero(),
199+
0x0000000000000000000000000000000000000000000000000000000000000001,
200+
);
178201
let bytes_2 = Bytes::from(raw_slice::from_parts::<u8>(__addr_of(b256_tuple_2), 64));
179202
let ed25519_2 = Ed25519::try_from(bytes_2).unwrap();
180203
assert(ed25519_2.bits()[63] == 1u8);
@@ -211,7 +234,10 @@ fn ed25519_into_b512() {
211234
let ed25519_1 = Ed25519::from(b512_1);
212235
assert(<Ed25519 as Into<B512>>::into(ed25519_1) == b512_1);
213236

214-
let b512_2 = B512::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
237+
let b512_2 = B512::from((
238+
b256::zero(),
239+
0x0000000000000000000000000000000000000000000000000000000000000001,
240+
));
215241
let ed25519_2 = Ed25519::from(b512_2);
216242
assert(<Ed25519 as Into<B512>>::into(ed25519_2) == b512_2);
217243

@@ -223,14 +249,19 @@ fn ed25519_into_b512() {
223249
#[test]
224250
fn ed25519_into_b256() {
225251
let ed25519_1 = Ed25519::from((b256::zero(), b256::zero()));
226-
let (result_1_1, result_2_1) = <Ed25519 as Into<(b256, b256)>>::into(ed25519_1);
252+
let (result_1_1, result_2_1) = <Ed25519 as Into<(b256, b256)>>::into(ed25519_1);
227253
assert(result_1_1 == b256::zero());
228254
assert(result_2_1 == b256::zero());
229255

230-
let ed25519_2 = Ed25519::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
256+
let ed25519_2 = Ed25519::from((
257+
b256::zero(),
258+
0x0000000000000000000000000000000000000000000000000000000000000001,
259+
));
231260
let (result_1_2, result_2_2): (b256, b256) = <Ed25519 as Into<(b256, b256)>>::into(ed25519_2);
232261
assert(result_1_2 == b256::zero());
233-
assert(result_2_2 == 0x0000000000000000000000000000000000000000000000000000000000000001);
262+
assert(
263+
result_2_2 == 0x0000000000000000000000000000000000000000000000000000000000000001,
264+
);
234265

235266
let ed25519_3 = Ed25519::from((b256::max(), b256::max()));
236267
let (result_1_3, result_2_3): (b256, b256) = <Ed25519 as Into<(b256, b256)>>::into(ed25519_3);
@@ -248,7 +279,10 @@ fn ed25519_into_bytes() {
248279
iter_1 += 1;
249280
}
250281

251-
let ed25519_2 = Ed25519::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
282+
let ed25519_2 = Ed25519::from((
283+
b256::zero(),
284+
0x0000000000000000000000000000000000000000000000000000000000000001,
285+
));
252286
let bytes_result_2: Bytes = <Ed25519 as Into<Bytes>>::into(ed25519_2);
253287
assert(bytes_result_2.get(63).unwrap() == 1u8);
254288
let mut iter_2 = 0;
@@ -270,8 +304,14 @@ fn ed25519_into_bytes() {
270304
fn ed25519_eq() {
271305
let ed25519_1 = Ed25519::from((b256::zero(), b256::zero()));
272306
let ed25519_2 = Ed25519::from((b256::zero(), b256::zero()));
273-
let ed25519_3 = Ed25519::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
274-
let ed25519_4 = Ed25519::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
307+
let ed25519_3 = Ed25519::from((
308+
b256::zero(),
309+
0x0000000000000000000000000000000000000000000000000000000000000001,
310+
));
311+
let ed25519_4 = Ed25519::from((
312+
b256::zero(),
313+
0x0000000000000000000000000000000000000000000000000000000000000001,
314+
));
275315
let ed25519_5 = Ed25519::from((b256::max(), b256::max()));
276316
let ed25519_6 = Ed25519::from((b256::max(), b256::max()));
277317

0 commit comments

Comments
 (0)