-
Notifications
You must be signed in to change notification settings - Fork 530
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
6 changed files
with
497 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
use super::{ | ||
StorageAsPath, StorageAsPointer, StoragePath, StoragePointer0Offset, Mutable, StoragePathTrait, | ||
StoragePathUpdateTrait, StoragePointerReadAccess, StoragePointerWriteAccess | ||
}; | ||
use core::Option; | ||
|
||
/// A type to represent a vec in storage. The length of the storage is stored in the storage | ||
/// base, while the elements are stored in hash(storage_base, index). | ||
#[phantom] | ||
pub struct Vec<T> {} | ||
|
||
impl VecDrop<T> of Drop<Vec<T>> {} | ||
impl VecCopy<T> of Copy<Vec<T>> {} | ||
|
||
/// Implement as_ptr for Vec. | ||
impl VecAsPointer<T> of StorageAsPointer<StoragePath<Vec<T>>> { | ||
type Value = u64; | ||
fn as_ptr(self: @StoragePath<Vec<T>>) -> StoragePointer0Offset<u64> { | ||
StoragePointer0Offset { address: (*self).finalize() } | ||
} | ||
} | ||
|
||
/// Implement as_ptr for Mutable<Vec>. | ||
impl MutableVecAsPointer<T> of StorageAsPointer<StoragePath<Mutable<Vec<T>>>> { | ||
type Value = Mutable<u64>; | ||
fn as_ptr(self: @StoragePath<Mutable<Vec<T>>>) -> StoragePointer0Offset<Mutable<u64>> { | ||
StoragePointer0Offset { address: (*self).finalize() } | ||
} | ||
} | ||
|
||
|
||
/// Trait for the interface of a storage vec. | ||
pub trait VecTrait<T> { | ||
type ElementType; | ||
fn get(self: T, index: u64) -> Option<StoragePath<Self::ElementType>>; | ||
fn len(self: T) -> u64; | ||
} | ||
|
||
/// Implement `VecTrait` for `StoragePath<Vec<T>>`. | ||
impl VecImpl<T> of VecTrait<StoragePath<Vec<T>>> { | ||
type ElementType = T; | ||
fn get(self: StoragePath<Vec<T>>, index: u64) -> Option<StoragePath<T>> { | ||
let vec_len = self.len(); | ||
if index < vec_len { | ||
Option::Some(self.update(index)) | ||
} else { | ||
Option::None | ||
} | ||
} | ||
fn len(self: StoragePath<Vec<T>>) -> u64 { | ||
self.as_ptr().read() | ||
} | ||
} | ||
|
||
/// Implement `VecTrait` for any type that implements StorageAsPath into a storage path | ||
/// that implements VecTrait. | ||
impl PathableVecImpl< | ||
T, | ||
+Drop<T>, | ||
impl PathImpl: StorageAsPath<T>, | ||
impl VecTraitImpl: VecTrait<StoragePath<PathImpl::Value>> | ||
> of VecTrait<T> { | ||
type ElementType = VecTraitImpl::ElementType; | ||
fn get(self: T, index: u64) -> Option<StoragePath<VecTraitImpl::ElementType>> { | ||
self.as_path().get(index) | ||
} | ||
fn len(self: T) -> u64 { | ||
self.as_path().len() | ||
} | ||
} | ||
|
||
/// Trait for the interface of a mutable storage vec. | ||
pub trait MutableVecTrait<T> { | ||
type ElementType; | ||
fn get(self: T, index: u64) -> Option<StoragePath<Mutable<Self::ElementType>>>; | ||
fn len(self: T) -> u64; | ||
fn append(self: T) -> StoragePath<Mutable<Self::ElementType>>; | ||
} | ||
|
||
/// Implement `MutableVecTrait` for `StoragePath<Mutable<Vec<T>>`. | ||
impl MutableVecImpl<T, +Drop<T>> of MutableVecTrait<StoragePath<Mutable<Vec<T>>>> { | ||
type ElementType = T; | ||
fn get(self: StoragePath<Mutable<Vec<T>>>, index: u64) -> Option<StoragePath<Mutable<T>>> { | ||
let vec_len = self.len(); | ||
if index < vec_len { | ||
Option::Some(self.update(index)) | ||
} else { | ||
Option::None | ||
} | ||
} | ||
fn len(self: StoragePath<Mutable<Vec<T>>>) -> u64 { | ||
self.as_ptr().read() | ||
} | ||
fn append(self: StoragePath<Mutable<Vec<T>>>) -> StoragePath<Mutable<T>> { | ||
let vec_len = self.len(); | ||
self.as_ptr().write(vec_len + 1); | ||
self.update(vec_len) | ||
} | ||
} | ||
|
||
/// Implement `MutableVecTrait` for any type that implements StorageAsPath into a storage | ||
/// path that implements MutableVecTrait. | ||
impl PathableMutableVecImpl< | ||
T, | ||
+Drop<T>, | ||
impl PathImpl: StorageAsPath<T>, | ||
impl VecTraitImpl: MutableVecTrait<StoragePath<PathImpl::Value>> | ||
> of MutableVecTrait<T> { | ||
type ElementType = VecTraitImpl::ElementType; | ||
fn get(self: T, index: u64) -> Option<StoragePath<Mutable<VecTraitImpl::ElementType>>> { | ||
self.as_path().get(index) | ||
} | ||
fn len(self: T) -> u64 { | ||
self.as_path().len() | ||
} | ||
fn append(self: T) -> StoragePath<Mutable<VecTraitImpl::ElementType>> { | ||
self.as_path().append() | ||
} | ||
} | ||
|
58 changes: 58 additions & 0 deletions
58
crates/cairo-lang-starknet/cairo_level_tests/collections_test.cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
use core::starknet::storage::StoragePointerReadAccess; | ||
use core::starknet::storage::MutableVecTrait; | ||
use core::starknet::storage::StoragePathEntry; | ||
|
||
|
||
#[starknet::contract] | ||
mod contract_with_map { | ||
use starknet::storage::Map; | ||
#[storage] | ||
struct Storage { | ||
simple: Map<u64, u32>, | ||
nested: Map<u64, Map<u64, u32>>, | ||
} | ||
} | ||
|
||
#[starknet::contract] | ||
mod contract_with_vec { | ||
use starknet::storage::Vec; | ||
#[storage] | ||
struct Storage { | ||
simple: Vec<u32>, | ||
nested: Vec<Vec<u32>>, | ||
} | ||
} | ||
|
||
#[test] | ||
fn test_simple_member_write_to_map() { | ||
let mut map_contract_state = contract_with_map::contract_state_for_testing(); | ||
let mut vec_contract_state = contract_with_vec::contract_state_for_testing(); | ||
let vec_entry = vec_contract_state.simple.append(); | ||
map_contract_state.simple.entry(0).write(1); | ||
assert_eq!(vec_entry.read(), 1); | ||
} | ||
|
||
#[test] | ||
fn test_simple_member_write_to_vec() { | ||
let mut map_contract_state = contract_with_map::contract_state_for_testing(); | ||
let mut vec_contract_state = contract_with_vec::contract_state_for_testing(); | ||
vec_contract_state.simple.append().write(1); | ||
assert_eq!(map_contract_state.simple.entry(0).read(), 1); | ||
} | ||
|
||
#[test] | ||
fn test_nested_member_write_to_map() { | ||
let mut map_contract_state = contract_with_map::contract_state_for_testing(); | ||
let mut vec_contract_state = contract_with_vec::contract_state_for_testing(); | ||
let vec_entry = vec_contract_state.nested.append().append(); | ||
map_contract_state.nested.entry(0).entry(0).write(1); | ||
assert_eq!(vec_entry.read(), 1); | ||
} | ||
|
||
#[test] | ||
fn test_nested_member_write_to_vec() { | ||
let mut map_contract_state = contract_with_map::contract_state_for_testing(); | ||
let mut vec_contract_state = contract_with_vec::contract_state_for_testing(); | ||
vec_contract_state.nested.append().append().write(1); | ||
assert_eq!(map_contract_state.nested.entry(0).entry(0).read(), 1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,3 +25,5 @@ mod storage_access; | |
#[cfg(test)] | ||
mod contract_address_test; | ||
mod utils; | ||
#[cfg(test)] | ||
mod collections_test; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.