From 747de239f62cb60304896894fd609802df9d27d2 Mon Sep 17 00:00:00 2001 From: mohiiit Date: Fri, 24 Nov 2023 01:35:14 +0530 Subject: [PATCH 1/6] added list exmaples and tests --- .../cairo_cheatsheet/src/lib.cairo | 4 + .../cairo_cheatsheet/src/list_example.cairo | 61 +++++++++++ .../cairo_cheatsheet/src/tests.cairo | 1 + .../src/tests/test_list_example.cairo | 101 ++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo create mode 100644 listings/ch00-getting-started/cairo_cheatsheet/src/tests.cairo create mode 100644 listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo diff --git a/listings/ch00-getting-started/cairo_cheatsheet/src/lib.cairo b/listings/ch00-getting-started/cairo_cheatsheet/src/lib.cairo index f3acd828..575da8b4 100644 --- a/listings/ch00-getting-started/cairo_cheatsheet/src/lib.cairo +++ b/listings/ch00-getting-started/cairo_cheatsheet/src/lib.cairo @@ -5,3 +5,7 @@ mod loop_example; mod match_example; mod struct_example; mod type_casting_example; +mod list_example; + +#[cfg(test)] +mod tests; diff --git a/listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo b/listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo new file mode 100644 index 00000000..eef9fec3 --- /dev/null +++ b/listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo @@ -0,0 +1,61 @@ +#[starknet::contract] +mod listExample { + use alexandria_storage::list::{List, ListTrait}; + + #[storage] + struct Storage { + amount: List, + tasks: List + } + + #[derive(Copy, Drop, Serde, starknet::Store)] + struct Task { + description: felt252, + status: felt252 + } + + + #[external(v0)] + #[generate_trait] + impl external of externalTrait { + fn add_in_amount(ref self: ContractState, number: u128) { + let mut current_amount_list = self.amount.read(); + current_amount_list.append(number); + } + + fn add_in_task(ref self: ContractState, description: felt252, status: felt252) { + let new_task = Task { description: description, status: status }; + let mut current_tasks_list = self.tasks.read(); + current_tasks_list.append(new_task); + } + + fn is_empty_list(ref self: ContractState) -> bool { + let mut current_amount_list = self.amount.read(); + current_amount_list.is_empty() + } + + fn list_length(ref self: ContractState) -> u32 { + let mut current_amount_list = self.amount.read(); + current_amount_list.len() + } + + fn get_from_index(ref self: ContractState, index: u32) -> u128 { + self.amount.read()[index] + } + + fn set_from_index(ref self: ContractState, index: u32, number: u128) { + let mut current_amount_list = self.amount.read(); + current_amount_list.set(index, number); + } + + fn pop_front_list(ref self: ContractState) { + let mut current_amount_list = self.amount.read(); + current_amount_list.pop_front(); + } + + fn array_conversion(ref self: ContractState) -> Array { + let mut current_amount_list = self.amount.read(); + current_amount_list.array() + } + } +} diff --git a/listings/ch00-getting-started/cairo_cheatsheet/src/tests.cairo b/listings/ch00-getting-started/cairo_cheatsheet/src/tests.cairo new file mode 100644 index 00000000..b862ce28 --- /dev/null +++ b/listings/ch00-getting-started/cairo_cheatsheet/src/tests.cairo @@ -0,0 +1 @@ +mod test_list_example; diff --git a/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo b/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo new file mode 100644 index 00000000..d4771d51 --- /dev/null +++ b/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo @@ -0,0 +1,101 @@ +use core::array::ArrayTrait; +use cairo_cheatsheet::list_example::listExample::{ + externalTrait, Task, amountContractMemberStateTrait, tasksContractMemberStateTrait +}; +use cairo_cheatsheet::list_example::listExample; + +fn STATE() -> listExample::ContractState { + listExample::contract_state_for_testing() +} + +#[test] +#[available_gas(2000000)] +fn test_add_in_amount() { + let mut state = STATE(); + state.add_in_amount(200); + assert(state.amount.read()[0] == 200, 'should be 200'); +} + +#[test] +#[available_gas(2000000)] +fn test_add_in_task() { + let mut state = STATE(); + state.add_in_task('test_description', 'test_status'); + let current_task: Task = state.tasks.read()[0]; + assert(current_task.description == 'test_description', 'should be test_description'); + assert(current_task.status == 'test_status', 'should be test_status'); +} + +#[test] +#[available_gas(2000000)] +fn test_is_empty_list() { + let mut state = STATE(); + + let pre_addition = state.is_empty_list(); + assert(pre_addition==true, 'should be true'); + + state.add_in_amount(200); + let post_addition = state.is_empty_list(); + assert(post_addition==false, 'should be false'); +} + +#[test] +#[available_gas(2000000)] +fn test_list_length() { + let mut state = STATE(); + + let pre_addition = state.list_length(); + assert(pre_addition==0, 'should be zero'); + + state.add_in_amount(200); + let post_addition = state.list_length(); + assert(post_addition==1, 'should be 1'); +} + +#[test] +#[available_gas(2000000)] +fn test_get_from_index() { + let mut state = STATE(); + state.add_in_amount(200); + let output = state.get_from_index(0); + assert(output == 200, 'should be 200'); +} + +#[test] +#[available_gas(2000000)] +fn test_set_from_index() { + let mut state = STATE(); + state.add_in_amount(200); + state.set_from_index(0, 400); + assert(state.amount.read()[0] == 400, 'should be 400'); +} + +#[test] +#[available_gas(2000000)] +fn test_pop_front_list() { + let mut state = STATE(); + + state.add_in_amount(200); + let pre_pop_front = state.list_length(); + assert(pre_pop_front==1, 'should be 1'); + + state.pop_front_list(); + let post_pop_front = state.list_length(); + assert(post_pop_front==0, 'should be zero'); +} + +#[test] +#[available_gas(2000000)] +fn test_array_conversion() { + let mut ideal_array = ArrayTrait::::new(); + ideal_array.append(200); + ideal_array.append(400); + + let mut state = STATE(); + + state.add_in_amount(200); + state.add_in_amount(400); + let output: Array = state.array_conversion(); + + assert(output==ideal_array, 'should be equal'); +} From e4adbcf3b7526f5830409ae3c92d743bd3682f41 Mon Sep 17 00:00:00 2001 From: mohiiit Date: Fri, 24 Nov 2023 01:41:15 +0530 Subject: [PATCH 2/6] list.md updated and formatted the code --- .../src/tests/test_list_example.cairo | 14 ++-- src/ch00/cairo_cheatsheet/list.md | 65 +++++++++++++++++++ 2 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 src/ch00/cairo_cheatsheet/list.md diff --git a/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo b/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo index d4771d51..b8d28a34 100644 --- a/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo +++ b/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo @@ -32,11 +32,11 @@ fn test_is_empty_list() { let mut state = STATE(); let pre_addition = state.is_empty_list(); - assert(pre_addition==true, 'should be true'); + assert(pre_addition == true, 'should be true'); state.add_in_amount(200); let post_addition = state.is_empty_list(); - assert(post_addition==false, 'should be false'); + assert(post_addition == false, 'should be false'); } #[test] @@ -45,11 +45,11 @@ fn test_list_length() { let mut state = STATE(); let pre_addition = state.list_length(); - assert(pre_addition==0, 'should be zero'); + assert(pre_addition == 0, 'should be zero'); state.add_in_amount(200); let post_addition = state.list_length(); - assert(post_addition==1, 'should be 1'); + assert(post_addition == 1, 'should be 1'); } #[test] @@ -77,11 +77,11 @@ fn test_pop_front_list() { state.add_in_amount(200); let pre_pop_front = state.list_length(); - assert(pre_pop_front==1, 'should be 1'); + assert(pre_pop_front == 1, 'should be 1'); state.pop_front_list(); let post_pop_front = state.list_length(); - assert(post_pop_front==0, 'should be zero'); + assert(post_pop_front == 0, 'should be zero'); } #[test] @@ -97,5 +97,5 @@ fn test_array_conversion() { state.add_in_amount(400); let output: Array = state.array_conversion(); - assert(output==ideal_array, 'should be equal'); + assert(output == ideal_array, 'should be equal'); } diff --git a/src/ch00/cairo_cheatsheet/list.md b/src/ch00/cairo_cheatsheet/list.md new file mode 100644 index 00000000..3c94fc4c --- /dev/null +++ b/src/ch00/cairo_cheatsheet/list.md @@ -0,0 +1,65 @@ +# List + +An ordered sequence of values that can be used in Starknet storage: + +```rust +#[storage] +stuct Storage { + amounts: List +} +``` + +### Interface + +```rust +trait ListTrait { + fn len(self: @List) -> u32; + fn is_empty(self: @List) -> bool; + fn append(ref self: List, value: T) -> u32; + fn get(self: @List, index: u32) -> Option; + fn set(ref self: List, index: u32, value: T); + fn pop_front(ref self: List) -> Option; + fn array(self: @List) -> Array; +} +``` + +`List` also implements `IndexView` so you can use the familiar bracket notation to access its members: + +```rust +let second = self.amounts.read()[1]; +``` + +Note that unlike `get`, using this bracket notation panics when accessing an out of bounds index. + +### Support for custom types + +`List` supports most of the corelib types out of the box. If you want to store a your own custom type in a `List`, it has to implement the `Store` trait. You can have the compiler derive it for you using the `#[derive(starknet::Store)]` attribute. + +### Caveats + +There are two idiosyncacies you should be aware of when using `List` + +1. The `append` operation costs 2 storage writes - one for the value itself and another one for updating the List's length +2. Due to a compiler limitation, it is not possible to use mutating operations with a single inline statement. For example, `self.amounts.read().append(42);` will not work. You have to do it in 2 steps: + +```rust +let mut amounts = self.amounts.read(); +amounts.append(42); +``` + +### Adding in project + +Update your project dependencies: +```rust + +[dependencies] +(...) +alexandria_storage = { git = "https://github.com/keep-starknet-strange/alexandria.git" } + +``` + +For example: + +```rust +{{#include ../../../listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo}} +``` \ No newline at end of file From d43b8d1eb9bb065aee57654acd72966a655e80fd Mon Sep 17 00:00:00 2001 From: mohiiit Date: Sun, 26 Nov 2023 12:04:15 +0530 Subject: [PATCH 3/6] documentation updated and replaced #external(v0) with #abi(embed_v0) --- .../cairo_cheatsheet/src/list_example.cairo | 6 +++--- .../cairo_cheatsheet/src/tests/test_list_example.cairo | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo b/listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo index eef9fec3..4a09f0f3 100644 --- a/listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo +++ b/listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo @@ -1,5 +1,5 @@ #[starknet::contract] -mod listExample { +mod ListExample { use alexandria_storage::list::{List, ListTrait}; #[storage] @@ -15,9 +15,9 @@ mod listExample { } - #[external(v0)] + #[abi(embed_v0)] #[generate_trait] - impl external of externalTrait { + impl External of ExternalTrait { fn add_in_amount(ref self: ContractState, number: u128) { let mut current_amount_list = self.amount.read(); current_amount_list.append(number); diff --git a/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo b/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo index b8d28a34..ea729ff7 100644 --- a/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo +++ b/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo @@ -1,11 +1,11 @@ use core::array::ArrayTrait; -use cairo_cheatsheet::list_example::listExample::{ - externalTrait, Task, amountContractMemberStateTrait, tasksContractMemberStateTrait +use cairo_cheatsheet::list_example::ListExample::{ + ExternalTrait, Task, amountContractMemberStateTrait, tasksContractMemberStateTrait }; -use cairo_cheatsheet::list_example::listExample; +use cairo_cheatsheet::list_example::ListExample; -fn STATE() -> listExample::ContractState { - listExample::contract_state_for_testing() +fn STATE() -> ListExample::ContractState { + ListExample::contract_state_for_testing() } #[test] From fa97d4c8ddc8f2a36b69dd3fb869b2ee2de5ac9a Mon Sep 17 00:00:00 2001 From: mohiiit Date: Sun, 26 Nov 2023 12:24:17 +0530 Subject: [PATCH 4/6] updated: list.md --- src/ch00/cairo_cheatsheet/list.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ch00/cairo_cheatsheet/list.md b/src/ch00/cairo_cheatsheet/list.md index 3c94fc4c..48145946 100644 --- a/src/ch00/cairo_cheatsheet/list.md +++ b/src/ch00/cairo_cheatsheet/list.md @@ -1,5 +1,10 @@ # List +By default, there is no list type supported in Cairo, but you can use Alexandria. To include a list in your Cairo project, refer to the [Alexandria documentation](https://github.com/keep-starknet-strange/alexandria/tree/main/src/storage) for instructions. + + +## What is a List? + An ordered sequence of values that can be used in Starknet storage: ```rust @@ -58,7 +63,7 @@ alexandria_storage = { git = "https://github.com/keep-starknet-strange/alexandri ``` -For example: +For example, let's use List to create a contract that tracks a list of amounts and tasks: ```rust {{#include ../../../listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo}} From 6510b652e3cf28659896f75941d01fb9142fba8b Mon Sep 17 00:00:00 2001 From: mohiiit Date: Sun, 26 Nov 2023 12:36:46 +0530 Subject: [PATCH 5/6] updated: SUMMARY.md --- src/SUMMARY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index edf3ff5a..5d43ced5 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -25,6 +25,7 @@ Summary - [Felt](./ch00/cairo_cheatsheet/felt.md) - [LegacyMap](./ch00/cairo_cheatsheet/mapping.md) - [Arrays](./ch00/cairo_cheatsheet/arrays.md) + - [List](./ch00/cairo_cheatsheet/list.md) - [Loop](./ch00/cairo_cheatsheet/loop.md) - [Match](./ch00/cairo_cheatsheet/match.md) - [Tuples](./ch00/cairo_cheatsheet/tuples.md) From 029f5600a478df0858e653881c64f885a618a141 Mon Sep 17 00:00:00 2001 From: mohiiit Date: Sun, 26 Nov 2023 15:55:58 +0530 Subject: [PATCH 6/6] list example moved to ch02 and defined interface --- .../cairo_cheatsheet/src/lib.cairo | 4 - .../cairo_cheatsheet/src/list_example.cairo | 61 ----------- .../cairo_cheatsheet/src/tests.cairo | 1 - .../src/tests/test_list_example.cairo | 101 ------------------ src/SUMMARY.md | 1 - src/ch00/cairo_cheatsheet/list.md | 70 ------------ src/ch02/list.md | 2 +- 7 files changed, 1 insertion(+), 239 deletions(-) delete mode 100644 listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo delete mode 100644 listings/ch00-getting-started/cairo_cheatsheet/src/tests.cairo delete mode 100644 listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo delete mode 100644 src/ch00/cairo_cheatsheet/list.md diff --git a/listings/ch00-getting-started/cairo_cheatsheet/src/lib.cairo b/listings/ch00-getting-started/cairo_cheatsheet/src/lib.cairo index 575da8b4..f3acd828 100644 --- a/listings/ch00-getting-started/cairo_cheatsheet/src/lib.cairo +++ b/listings/ch00-getting-started/cairo_cheatsheet/src/lib.cairo @@ -5,7 +5,3 @@ mod loop_example; mod match_example; mod struct_example; mod type_casting_example; -mod list_example; - -#[cfg(test)] -mod tests; diff --git a/listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo b/listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo deleted file mode 100644 index 4a09f0f3..00000000 --- a/listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo +++ /dev/null @@ -1,61 +0,0 @@ -#[starknet::contract] -mod ListExample { - use alexandria_storage::list::{List, ListTrait}; - - #[storage] - struct Storage { - amount: List, - tasks: List - } - - #[derive(Copy, Drop, Serde, starknet::Store)] - struct Task { - description: felt252, - status: felt252 - } - - - #[abi(embed_v0)] - #[generate_trait] - impl External of ExternalTrait { - fn add_in_amount(ref self: ContractState, number: u128) { - let mut current_amount_list = self.amount.read(); - current_amount_list.append(number); - } - - fn add_in_task(ref self: ContractState, description: felt252, status: felt252) { - let new_task = Task { description: description, status: status }; - let mut current_tasks_list = self.tasks.read(); - current_tasks_list.append(new_task); - } - - fn is_empty_list(ref self: ContractState) -> bool { - let mut current_amount_list = self.amount.read(); - current_amount_list.is_empty() - } - - fn list_length(ref self: ContractState) -> u32 { - let mut current_amount_list = self.amount.read(); - current_amount_list.len() - } - - fn get_from_index(ref self: ContractState, index: u32) -> u128 { - self.amount.read()[index] - } - - fn set_from_index(ref self: ContractState, index: u32, number: u128) { - let mut current_amount_list = self.amount.read(); - current_amount_list.set(index, number); - } - - fn pop_front_list(ref self: ContractState) { - let mut current_amount_list = self.amount.read(); - current_amount_list.pop_front(); - } - - fn array_conversion(ref self: ContractState) -> Array { - let mut current_amount_list = self.amount.read(); - current_amount_list.array() - } - } -} diff --git a/listings/ch00-getting-started/cairo_cheatsheet/src/tests.cairo b/listings/ch00-getting-started/cairo_cheatsheet/src/tests.cairo deleted file mode 100644 index b862ce28..00000000 --- a/listings/ch00-getting-started/cairo_cheatsheet/src/tests.cairo +++ /dev/null @@ -1 +0,0 @@ -mod test_list_example; diff --git a/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo b/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo deleted file mode 100644 index ea729ff7..00000000 --- a/listings/ch00-getting-started/cairo_cheatsheet/src/tests/test_list_example.cairo +++ /dev/null @@ -1,101 +0,0 @@ -use core::array::ArrayTrait; -use cairo_cheatsheet::list_example::ListExample::{ - ExternalTrait, Task, amountContractMemberStateTrait, tasksContractMemberStateTrait -}; -use cairo_cheatsheet::list_example::ListExample; - -fn STATE() -> ListExample::ContractState { - ListExample::contract_state_for_testing() -} - -#[test] -#[available_gas(2000000)] -fn test_add_in_amount() { - let mut state = STATE(); - state.add_in_amount(200); - assert(state.amount.read()[0] == 200, 'should be 200'); -} - -#[test] -#[available_gas(2000000)] -fn test_add_in_task() { - let mut state = STATE(); - state.add_in_task('test_description', 'test_status'); - let current_task: Task = state.tasks.read()[0]; - assert(current_task.description == 'test_description', 'should be test_description'); - assert(current_task.status == 'test_status', 'should be test_status'); -} - -#[test] -#[available_gas(2000000)] -fn test_is_empty_list() { - let mut state = STATE(); - - let pre_addition = state.is_empty_list(); - assert(pre_addition == true, 'should be true'); - - state.add_in_amount(200); - let post_addition = state.is_empty_list(); - assert(post_addition == false, 'should be false'); -} - -#[test] -#[available_gas(2000000)] -fn test_list_length() { - let mut state = STATE(); - - let pre_addition = state.list_length(); - assert(pre_addition == 0, 'should be zero'); - - state.add_in_amount(200); - let post_addition = state.list_length(); - assert(post_addition == 1, 'should be 1'); -} - -#[test] -#[available_gas(2000000)] -fn test_get_from_index() { - let mut state = STATE(); - state.add_in_amount(200); - let output = state.get_from_index(0); - assert(output == 200, 'should be 200'); -} - -#[test] -#[available_gas(2000000)] -fn test_set_from_index() { - let mut state = STATE(); - state.add_in_amount(200); - state.set_from_index(0, 400); - assert(state.amount.read()[0] == 400, 'should be 400'); -} - -#[test] -#[available_gas(2000000)] -fn test_pop_front_list() { - let mut state = STATE(); - - state.add_in_amount(200); - let pre_pop_front = state.list_length(); - assert(pre_pop_front == 1, 'should be 1'); - - state.pop_front_list(); - let post_pop_front = state.list_length(); - assert(post_pop_front == 0, 'should be zero'); -} - -#[test] -#[available_gas(2000000)] -fn test_array_conversion() { - let mut ideal_array = ArrayTrait::::new(); - ideal_array.append(200); - ideal_array.append(400); - - let mut state = STATE(); - - state.add_in_amount(200); - state.add_in_amount(400); - let output: Array = state.array_conversion(); - - assert(output == ideal_array, 'should be equal'); -} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 5d43ced5..edf3ff5a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -25,7 +25,6 @@ Summary - [Felt](./ch00/cairo_cheatsheet/felt.md) - [LegacyMap](./ch00/cairo_cheatsheet/mapping.md) - [Arrays](./ch00/cairo_cheatsheet/arrays.md) - - [List](./ch00/cairo_cheatsheet/list.md) - [Loop](./ch00/cairo_cheatsheet/loop.md) - [Match](./ch00/cairo_cheatsheet/match.md) - [Tuples](./ch00/cairo_cheatsheet/tuples.md) diff --git a/src/ch00/cairo_cheatsheet/list.md b/src/ch00/cairo_cheatsheet/list.md deleted file mode 100644 index 48145946..00000000 --- a/src/ch00/cairo_cheatsheet/list.md +++ /dev/null @@ -1,70 +0,0 @@ -# List - -By default, there is no list type supported in Cairo, but you can use Alexandria. To include a list in your Cairo project, refer to the [Alexandria documentation](https://github.com/keep-starknet-strange/alexandria/tree/main/src/storage) for instructions. - - -## What is a List? - -An ordered sequence of values that can be used in Starknet storage: - -```rust -#[storage] -stuct Storage { - amounts: List -} -``` - -### Interface - -```rust -trait ListTrait { - fn len(self: @List) -> u32; - fn is_empty(self: @List) -> bool; - fn append(ref self: List, value: T) -> u32; - fn get(self: @List, index: u32) -> Option; - fn set(ref self: List, index: u32, value: T); - fn pop_front(ref self: List) -> Option; - fn array(self: @List) -> Array; -} -``` - -`List` also implements `IndexView` so you can use the familiar bracket notation to access its members: - -```rust -let second = self.amounts.read()[1]; -``` - -Note that unlike `get`, using this bracket notation panics when accessing an out of bounds index. - -### Support for custom types - -`List` supports most of the corelib types out of the box. If you want to store a your own custom type in a `List`, it has to implement the `Store` trait. You can have the compiler derive it for you using the `#[derive(starknet::Store)]` attribute. - -### Caveats - -There are two idiosyncacies you should be aware of when using `List` - -1. The `append` operation costs 2 storage writes - one for the value itself and another one for updating the List's length -2. Due to a compiler limitation, it is not possible to use mutating operations with a single inline statement. For example, `self.amounts.read().append(42);` will not work. You have to do it in 2 steps: - -```rust -let mut amounts = self.amounts.read(); -amounts.append(42); -``` - -### Adding in project - -Update your project dependencies: -```rust - -[dependencies] -(...) -alexandria_storage = { git = "https://github.com/keep-starknet-strange/alexandria.git" } - -``` - -For example, let's use List to create a contract that tracks a list of amounts and tasks: - -```rust -{{#include ../../../listings/ch00-getting-started/cairo_cheatsheet/src/list_example.cairo}} -``` \ No newline at end of file diff --git a/src/ch02/list.md b/src/ch02/list.md index 4613dbe9..d2a06090 100644 --- a/src/ch02/list.md +++ b/src/ch02/list.md @@ -63,5 +63,5 @@ alexandria_storage = { git = "https://github.com/keep-starknet-strange/alexandri For example, let's use `List` to create a contract that tracks a list of amounts and tasks: ```rust -{{#include ../../../listings/ch02-advanced-concepts/using-lists/src/contract.cairo}} +{{#include ../../listings/ch02-advanced-concepts/using_lists/src/contract.cairo}} ``` \ No newline at end of file