diff --git a/packages/society/src/components/followable.cairo b/packages/society/src/components/followable.cairo index 8c37e24..5815ae9 100644 --- a/packages/society/src/components/followable.cairo +++ b/packages/society/src/components/followable.cairo @@ -22,5 +22,24 @@ mod FollowableComponent { #[generate_trait] impl InternalImpl< TContractState, +HasComponent - > of InternalTrait {} + > of InternalTrait { + fn follow(self: @ComponentState, world: WorldStorage, followed: felt252) { + // [Setup] Datastore + let mut store = StoreTrait::new(world); + + // [Effect] Follow + let follower = starknet::get_caller_address().into(); + let time = starknet::get_block_timestamp(); + store.follow(follower, followed, time); + } + + fn unfollow(self: @ComponentState, world: WorldStorage, followed: felt252) { + // [Setup] Datastore + let mut store = StoreTrait::new(world); + + // [Effect] Unfollow + let follower = starknet::get_caller_address().into(); + store.unfollow(follower, followed); + } + } } diff --git a/packages/society/src/events/follow.cairo b/packages/society/src/events/follow.cairo new file mode 100644 index 0000000..08b414d --- /dev/null +++ b/packages/society/src/events/follow.cairo @@ -0,0 +1,72 @@ +// Internal imports + +use society::events::index::Follow; + +// Errors + +pub mod errors { + pub const FOLLOW_INVALID_FOLLOWER: felt252 = 'Follow: invalid follower'; + pub const FOLLOW_INVALID_FOLLOWED: felt252 = 'Follow: invalid followed'; +} + +// Implementations + +#[generate_trait] +impl FollowImpl of FollowTrait { + #[inline] + fn new(follower: felt252, followed: felt252, time: u64,) -> Follow { + // [Check] Inputs + // [Info] We don't check points here, leave free the game to decide + FollowAssert::assert_valid_follower(follower); + FollowAssert::assert_valid_followed(followed); + // [Return] Follow + Follow { follower, followed, time } + } +} + +#[generate_trait] +impl FollowAssert of AssertTrait { + #[inline] + fn assert_valid_follower(follower: felt252) { + assert(follower != 0, errors::FOLLOW_INVALID_FOLLOWER); + } + + #[inline] + fn assert_valid_followed(followed: felt252) { + assert(followed != 0, errors::FOLLOW_INVALID_FOLLOWED); + } +} + +#[cfg(test)] +mod tests { + // Local imports + + use super::{Follow, FollowTrait}; + + // Constants + + const FOLLOWER: felt252 = 'FOLLOWER'; + const FOLLOWED: felt252 = 'FOLLOWED'; + const TIME: u64 = 100; + + #[test] + fn test_follow_new() { + let follow = FollowTrait::new(FOLLOWER, FOLLOWED, TIME); + assert_eq!(follow.follower, FOLLOWER); + assert_eq!(follow.followed, FOLLOWED); + assert_eq!(follow.time, TIME); + } + + #[test] + #[should_panic(expected: ('Follow: invalid follower',))] + fn test_follow_new_invalid_follower() { + FollowTrait::new(0, FOLLOWED, TIME); + } + + #[test] + #[should_panic(expected: ('Follow: invalid followed',))] + fn test_follow_new_invalid_followed() { + FollowTrait::new(FOLLOWER, 0, TIME); + } +} + diff --git a/packages/society/src/events/index.cairo b/packages/society/src/events/index.cairo index c10279e..d44df24 100644 --- a/packages/society/src/events/index.cairo +++ b/packages/society/src/events/index.cairo @@ -4,7 +4,7 @@ #[dojo::event] pub struct Follow { #[key] - account_id: felt252, - follower_id: felt252, + follower: felt252, + followed: felt252, time: u64, } diff --git a/packages/society/src/lib.cairo b/packages/society/src/lib.cairo index 2a85d21..c803c29 100644 --- a/packages/society/src/lib.cairo +++ b/packages/society/src/lib.cairo @@ -5,6 +5,11 @@ mod types { mod role; } +mod events { + mod index; + mod follow; +} + mod models { mod index; mod member; diff --git a/packages/society/src/store.cairo b/packages/society/src/store.cairo index 9573421..4f74be0 100644 --- a/packages/society/src/store.cairo +++ b/packages/society/src/store.cairo @@ -8,13 +8,14 @@ use starknet::SyscallResultTrait; use dojo::world::WorldStorage; use dojo::model::ModelStorage; +use dojo::event::EventStorage; // Models imports use society::models::alliance::Alliance; use society::models::guild::Guild; use society::models::member::Member; - +use society::events::follow::{Follow, FollowTrait}; // Structs @@ -61,4 +62,16 @@ impl StoreImpl of StoreTrait { fn set_member(ref self: Store, member: @Member) { self.world.write_model(member); } + + #[inline] + fn follow(ref self: Store, follower: felt252, followed: felt252, time: u64) { + let event = FollowTrait::new(follower, followed, time); + self.world.emit_event(@event); + } + + #[inline] + fn unfollow(ref self: Store, follower: felt252, followed: felt252) { + let event = FollowTrait::new(follower, followed, 0); + self.world.emit_event(@event); + } }