From a240e4c43f2eb6004e8f83c190411a6f9e596226 Mon Sep 17 00:00:00 2001 From: z80 Date: Thu, 28 Nov 2024 10:36:38 -0500 Subject: [PATCH] compile examples --- tests/compiled-examples/calculator.rs | 454 ------------- tests/compiled-examples/constants.rs | 279 -------- tests/compiled-examples/event.rs | 326 --------- tests/compiled-examples/fizzbuzz.rs | 370 ---------- tests/compiled-examples/hello.rs | 409 ------------ tests/compiled-examples/pyth.rs | 286 -------- tests/compiled-examples/stored_mutables.rs | 742 --------------------- tests/compiled-test-cases/account_key.rs | 365 ---------- 8 files changed, 3231 deletions(-) diff --git a/tests/compiled-examples/calculator.rs b/tests/compiled-examples/calculator.rs index f6c9539..e69de29 100644 --- a/tests/compiled-examples/calculator.rs +++ b/tests/compiled-examples/calculator.rs @@ -1,454 +0,0 @@ -// ===== dot/mod.rs ===== - -pub mod program; - -// ===== dot/program.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] -use crate::{id, seahorse_util::*}; -use anchor_lang::{prelude::*, solana_program}; -use anchor_spl::token::{self, Mint, Token, TokenAccount}; -use std::{cell::RefCell, rc::Rc}; - -#[account] -#[derive(Debug)] -pub struct Calculator { - pub owner: Pubkey, - pub display: i64, -} - -impl<'info, 'entrypoint> Calculator { - pub fn load( - account: &'entrypoint mut Box>, - programs_map: &'entrypoint ProgramsMap<'info>, - ) -> Mutable> { - let owner = account.owner.clone(); - let display = account.display; - - Mutable::new(LoadedCalculator { - __account__: account, - __programs__: programs_map, - owner, - display, - }) - } - - pub fn store(loaded: Mutable) { - let mut loaded = loaded.borrow_mut(); - let owner = loaded.owner.clone(); - - loaded.__account__.owner = owner; - - let display = loaded.display; - - loaded.__account__.display = display; - } -} - -#[derive(Debug)] -pub struct LoadedCalculator<'info, 'entrypoint> { - pub __account__: &'entrypoint mut Box>, - pub __programs__: &'entrypoint ProgramsMap<'info>, - pub owner: Pubkey, - pub display: i64, -} - -#[derive(Clone, Debug, PartialEq, AnchorSerialize, AnchorDeserialize, Copy)] -pub enum Operation { - ADD, - SUB, - MUL, - DIV, -} - -impl Default for Operation { - fn default() -> Self { - Operation::ADD - } -} - -pub fn do_operation_handler<'info>( - mut owner: SeahorseSigner<'info, '_>, - mut calculator: Mutable>, - mut op: Operation, - mut num: i64, -) -> () { - if !(owner.key() == calculator.borrow().owner) { - panic!("This is not your calculator!"); - } - - if op == Operation::ADD { - assign!( - calculator.borrow_mut().display, - calculator.borrow().display + num - ); - } else { - if op == Operation::SUB { - assign!( - calculator.borrow_mut().display, - calculator.borrow().display - num - ); - } else { - if op == Operation::MUL { - assign!( - calculator.borrow_mut().display, - calculator.borrow().display * num - ); - } else { - if op == Operation::DIV { - assign!( - calculator.borrow_mut().display, - calculator.borrow().display / num - ); - } - } - } - } -} - -pub fn init_calculator_handler<'info>( - mut owner: SeahorseSigner<'info, '_>, - mut calculator: Empty>>, -) -> () { - let mut calculator = calculator.account.clone(); - - assign!(calculator.borrow_mut().owner, owner.key()); -} - -pub fn reset_calculator_handler<'info>( - mut owner: SeahorseSigner<'info, '_>, - mut calculator: Mutable>, -) -> () { - solana_program::msg!( - "{:?} {} {:?}", - owner.key(), - "is resetting a calculator".to_string(), - calculator.borrow().__account__.key() - ); - - if !(owner.key() == calculator.borrow().owner) { - panic!("This is not your calculator!"); - } - - assign!(calculator.borrow_mut().display, 0); -} - -// ===== lib.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] - -pub mod dot; - -use anchor_lang::prelude::*; -use anchor_spl::{ - associated_token::{self, AssociatedToken}, - token::{self, Mint, Token, TokenAccount}, -}; - -use dot::program::*; -use std::{cell::RefCell, rc::Rc}; - -declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); - -pub mod seahorse_util { - use super::*; - use std::{ - collections::HashMap, - fmt::Debug, - ops::{Deref, Index, IndexMut}, - }; - - pub struct Mutable(Rc>); - - impl Mutable { - pub fn new(obj: T) -> Self { - Self(Rc::new(RefCell::new(obj))) - } - } - - impl Clone for Mutable { - fn clone(&self) -> Self { - Self(self.0.clone()) - } - } - - impl Deref for Mutable { - type Target = Rc>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - impl Debug for Mutable { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - - impl Default for Mutable { - fn default() -> Self { - Self::new(T::default()) - } - } - - pub trait IndexWrapped { - type Output; - - fn index_wrapped(&self, index: i128) -> &Self::Output; - } - - pub trait IndexWrappedMut: IndexWrapped { - fn index_wrapped_mut(&mut self, index: i128) -> &mut ::Output; - } - - impl IndexWrapped for Vec { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for Vec { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - impl IndexWrapped for [T; N] { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for [T; N] { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - #[derive(Clone)] - pub struct Empty { - pub account: T, - pub bump: Option, - } - - #[derive(Clone, Debug)] - pub struct ProgramsMap<'info>(pub HashMap<&'static str, AccountInfo<'info>>); - - impl<'info> ProgramsMap<'info> { - pub fn get(&self, name: &'static str) -> AccountInfo<'info> { - self.0.get(name).unwrap().clone() - } - } - - #[derive(Clone, Debug)] - pub struct WithPrograms<'info, 'entrypoint, A> { - pub account: &'entrypoint A, - pub programs: &'entrypoint ProgramsMap<'info>, - } - - impl<'info, 'entrypoint, A> Deref for WithPrograms<'info, 'entrypoint, A> { - type Target = A; - - fn deref(&self) -> &Self::Target { - &self.account - } - } - - pub type SeahorseAccount<'info, 'entrypoint, A> = - WithPrograms<'info, 'entrypoint, Box>>; - - pub type SeahorseSigner<'info, 'entrypoint> = WithPrograms<'info, 'entrypoint, Signer<'info>>; - - #[derive(Clone, Debug)] - pub struct CpiAccount<'info> { - #[doc = "CHECK: CpiAccounts temporarily store AccountInfos."] - pub account_info: AccountInfo<'info>, - pub is_writable: bool, - pub is_signer: bool, - pub seeds: Option>>, - } - - #[macro_export] - macro_rules! seahorse_const { - ($ name : ident , $ value : expr) => { - macro_rules! $name { - () => { - $value - }; - } - - pub(crate) use $name; - }; - } - - pub trait Loadable { - type Loaded; - - fn load(stored: Self) -> Self::Loaded; - - fn store(loaded: Self::Loaded) -> Self; - } - - macro_rules! Loaded { - ($ name : ty) => { - <$name as Loadable>::Loaded - }; - } - - pub(crate) use Loaded; - - #[macro_export] - macro_rules! assign { - ($ lval : expr , $ rval : expr) => {{ - let temp = $rval; - - $lval = temp; - }}; - } - - #[macro_export] - macro_rules! index_assign { - ($ lval : expr , $ idx : expr , $ rval : expr) => { - let temp_rval = $rval; - let temp_idx = $idx; - - $lval[temp_idx] = temp_rval; - }; - } - - pub(crate) use assign; - - pub(crate) use index_assign; - - pub(crate) use seahorse_const; -} - -#[program] -mod calculator { - use super::*; - use seahorse_util::*; - use std::collections::HashMap; - - #[derive(Accounts)] - # [instruction (op : Operation , num : i64)] - pub struct DoOperation<'info> { - #[account(mut)] - pub owner: Signer<'info>, - #[account(mut)] - pub calculator: Box>, - } - - pub fn do_operation(ctx: Context, op: Operation, num: i64) -> Result<()> { - let mut programs = HashMap::new(); - let programs_map = ProgramsMap(programs); - let owner = SeahorseSigner { - account: &ctx.accounts.owner, - programs: &programs_map, - }; - - let calculator = - dot::program::Calculator::load(&mut ctx.accounts.calculator, &programs_map); - - do_operation_handler(owner.clone(), calculator.clone(), op, num); - - dot::program::Calculator::store(calculator); - - return Ok(()); - } - - #[derive(Accounts)] - pub struct InitCalculator<'info> { - #[account(mut)] - pub owner: Signer<'info>, - # [account (init , space = std :: mem :: size_of :: < dot :: program :: Calculator > () + 8 , payer = owner , seeds = ["Calculator" . as_bytes () . as_ref () , owner . key () . as_ref ()] , bump)] - pub calculator: Box>, - pub rent: Sysvar<'info, Rent>, - pub system_program: Program<'info, System>, - } - - pub fn init_calculator(ctx: Context) -> Result<()> { - let mut programs = HashMap::new(); - - programs.insert( - "system_program", - ctx.accounts.system_program.to_account_info(), - ); - - let programs_map = ProgramsMap(programs); - let owner = SeahorseSigner { - account: &ctx.accounts.owner, - programs: &programs_map, - }; - - let calculator = Empty { - account: dot::program::Calculator::load(&mut ctx.accounts.calculator, &programs_map), - bump: Some(ctx.bumps.calculator), - }; - - init_calculator_handler(owner.clone(), calculator.clone()); - - dot::program::Calculator::store(calculator.account); - - return Ok(()); - } - - #[derive(Accounts)] - pub struct ResetCalculator<'info> { - #[account(mut)] - pub owner: Signer<'info>, - #[account(mut)] - pub calculator: Box>, - } - - pub fn reset_calculator(ctx: Context) -> Result<()> { - let mut programs = HashMap::new(); - let programs_map = ProgramsMap(programs); - let owner = SeahorseSigner { - account: &ctx.accounts.owner, - programs: &programs_map, - }; - - let calculator = - dot::program::Calculator::load(&mut ctx.accounts.calculator, &programs_map); - - reset_calculator_handler(owner.clone(), calculator.clone()); - - dot::program::Calculator::store(calculator); - - return Ok(()); - } -} - diff --git a/tests/compiled-examples/constants.rs b/tests/compiled-examples/constants.rs index b78f1c0..e69de29 100644 --- a/tests/compiled-examples/constants.rs +++ b/tests/compiled-examples/constants.rs @@ -1,279 +0,0 @@ -// ===== dot/mod.rs ===== - -pub mod program; - -// ===== dot/program.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] -use crate::{id, seahorse_util::*}; -use anchor_lang::{prelude::*, solana_program}; -use anchor_spl::token::{self, Mint, Token, TokenAccount}; -use std::{cell::RefCell, rc::Rc}; - -seahorse_const! { MAX , 7 } - -seahorse_const! { MESSAGE , "Hello constants" . to_string () } - -seahorse_const! { MIN , 2 } - -seahorse_const! { RANGE , (MAX ! () - MIN ! ()) } - -pub fn use_constants_handler<'info>(mut signer: SeahorseSigner<'info, '_>) -> () { - solana_program::msg!("{}", MESSAGE!()); - - for mut i in MIN!()..MAX!() { - solana_program::msg!("{} {}", "Step:".to_string(), i); - } - - solana_program::msg!("{} {}", "Range:".to_string(), RANGE!()); -} - -// ===== lib.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] - -pub mod dot; - -use anchor_lang::prelude::*; -use anchor_spl::{ - associated_token::{self, AssociatedToken}, - token::{self, Mint, Token, TokenAccount}, -}; - -use dot::program::*; -use std::{cell::RefCell, rc::Rc}; - -declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); - -pub mod seahorse_util { - use super::*; - use std::{ - collections::HashMap, - fmt::Debug, - ops::{Deref, Index, IndexMut}, - }; - - pub struct Mutable(Rc>); - - impl Mutable { - pub fn new(obj: T) -> Self { - Self(Rc::new(RefCell::new(obj))) - } - } - - impl Clone for Mutable { - fn clone(&self) -> Self { - Self(self.0.clone()) - } - } - - impl Deref for Mutable { - type Target = Rc>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - impl Debug for Mutable { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - - impl Default for Mutable { - fn default() -> Self { - Self::new(T::default()) - } - } - - pub trait IndexWrapped { - type Output; - - fn index_wrapped(&self, index: i128) -> &Self::Output; - } - - pub trait IndexWrappedMut: IndexWrapped { - fn index_wrapped_mut(&mut self, index: i128) -> &mut ::Output; - } - - impl IndexWrapped for Vec { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for Vec { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - impl IndexWrapped for [T; N] { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for [T; N] { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - #[derive(Clone)] - pub struct Empty { - pub account: T, - pub bump: Option, - } - - #[derive(Clone, Debug)] - pub struct ProgramsMap<'info>(pub HashMap<&'static str, AccountInfo<'info>>); - - impl<'info> ProgramsMap<'info> { - pub fn get(&self, name: &'static str) -> AccountInfo<'info> { - self.0.get(name).unwrap().clone() - } - } - - #[derive(Clone, Debug)] - pub struct WithPrograms<'info, 'entrypoint, A> { - pub account: &'entrypoint A, - pub programs: &'entrypoint ProgramsMap<'info>, - } - - impl<'info, 'entrypoint, A> Deref for WithPrograms<'info, 'entrypoint, A> { - type Target = A; - - fn deref(&self) -> &Self::Target { - &self.account - } - } - - pub type SeahorseAccount<'info, 'entrypoint, A> = - WithPrograms<'info, 'entrypoint, Box>>; - - pub type SeahorseSigner<'info, 'entrypoint> = WithPrograms<'info, 'entrypoint, Signer<'info>>; - - #[derive(Clone, Debug)] - pub struct CpiAccount<'info> { - #[doc = "CHECK: CpiAccounts temporarily store AccountInfos."] - pub account_info: AccountInfo<'info>, - pub is_writable: bool, - pub is_signer: bool, - pub seeds: Option>>, - } - - #[macro_export] - macro_rules! seahorse_const { - ($ name : ident , $ value : expr) => { - macro_rules! $name { - () => { - $value - }; - } - - pub(crate) use $name; - }; - } - - pub trait Loadable { - type Loaded; - - fn load(stored: Self) -> Self::Loaded; - - fn store(loaded: Self::Loaded) -> Self; - } - - macro_rules! Loaded { - ($ name : ty) => { - <$name as Loadable>::Loaded - }; - } - - pub(crate) use Loaded; - - #[macro_export] - macro_rules! assign { - ($ lval : expr , $ rval : expr) => {{ - let temp = $rval; - - $lval = temp; - }}; - } - - #[macro_export] - macro_rules! index_assign { - ($ lval : expr , $ idx : expr , $ rval : expr) => { - let temp_rval = $rval; - let temp_idx = $idx; - - $lval[temp_idx] = temp_rval; - }; - } - - pub(crate) use assign; - - pub(crate) use index_assign; - - pub(crate) use seahorse_const; -} - -#[program] -mod constants { - use super::*; - use seahorse_util::*; - use std::collections::HashMap; - - #[derive(Accounts)] - pub struct UseConstants<'info> { - #[account(mut)] - pub signer: Signer<'info>, - } - - pub fn use_constants(ctx: Context) -> Result<()> { - let mut programs = HashMap::new(); - let programs_map = ProgramsMap(programs); - let signer = SeahorseSigner { - account: &ctx.accounts.signer, - programs: &programs_map, - }; - - use_constants_handler(signer.clone()); - - return Ok(()); - } -} - diff --git a/tests/compiled-examples/event.rs b/tests/compiled-examples/event.rs index b21d4b5..e69de29 100644 --- a/tests/compiled-examples/event.rs +++ b/tests/compiled-examples/event.rs @@ -1,326 +0,0 @@ -// ===== dot/mod.rs ===== - -pub mod program; - -// ===== dot/program.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] -use crate::{id, seahorse_util::*}; -use anchor_lang::{prelude::*, solana_program}; -use anchor_spl::token::{self, Mint, Token, TokenAccount}; -use std::{cell::RefCell, rc::Rc}; - -#[event] -pub struct HelloEvent { - pub data: u8, - pub title: String, - pub owner: Pubkey, -} - -#[derive(Clone, Debug, Default)] -pub struct LoadedHelloEvent { - pub data: u8, - pub title: String, - pub owner: Pubkey, -} - -impl Mutable { - fn __emit__(&self) { - let e = self.borrow(); - - emit!(HelloEvent { - data: e.data, - title: e.title.clone(), - owner: e.owner.clone() - }) - } -} - -impl LoadedHelloEvent { - pub fn __new__(data: u8, title: String, owner: Pubkey) -> Mutable { - let obj = LoadedHelloEvent { data, title, owner }; - - return Mutable::new(obj); - } -} - -impl Loadable for HelloEvent { - type Loaded = LoadedHelloEvent; - - fn load(stored: Self) -> Self::Loaded { - Self::Loaded { - data: stored.data, - title: stored.title, - owner: stored.owner, - } - } - - fn store(loaded: Self::Loaded) -> Self { - Self { - data: loaded.data, - title: loaded.title.clone(), - owner: loaded.owner.clone(), - } - } -} - -pub fn send_event_handler<'info>( - mut sender: SeahorseSigner<'info, '_>, - mut data: u8, - mut title: String, -) -> () { - let mut event = ::__new__(data.clone(), title.clone(), sender.key()); - - event.__emit__(); -} - -// ===== lib.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] - -pub mod dot; - -use anchor_lang::prelude::*; -use anchor_spl::{ - associated_token::{self, AssociatedToken}, - token::{self, Mint, Token, TokenAccount}, -}; - -use dot::program::*; -use std::{cell::RefCell, rc::Rc}; - -declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); - -pub mod seahorse_util { - use super::*; - use std::{ - collections::HashMap, - fmt::Debug, - ops::{Deref, Index, IndexMut}, - }; - - pub struct Mutable(Rc>); - - impl Mutable { - pub fn new(obj: T) -> Self { - Self(Rc::new(RefCell::new(obj))) - } - } - - impl Clone for Mutable { - fn clone(&self) -> Self { - Self(self.0.clone()) - } - } - - impl Deref for Mutable { - type Target = Rc>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - impl Debug for Mutable { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - - impl Default for Mutable { - fn default() -> Self { - Self::new(T::default()) - } - } - - pub trait IndexWrapped { - type Output; - - fn index_wrapped(&self, index: i128) -> &Self::Output; - } - - pub trait IndexWrappedMut: IndexWrapped { - fn index_wrapped_mut(&mut self, index: i128) -> &mut ::Output; - } - - impl IndexWrapped for Vec { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for Vec { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - impl IndexWrapped for [T; N] { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for [T; N] { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - #[derive(Clone)] - pub struct Empty { - pub account: T, - pub bump: Option, - } - - #[derive(Clone, Debug)] - pub struct ProgramsMap<'info>(pub HashMap<&'static str, AccountInfo<'info>>); - - impl<'info> ProgramsMap<'info> { - pub fn get(&self, name: &'static str) -> AccountInfo<'info> { - self.0.get(name).unwrap().clone() - } - } - - #[derive(Clone, Debug)] - pub struct WithPrograms<'info, 'entrypoint, A> { - pub account: &'entrypoint A, - pub programs: &'entrypoint ProgramsMap<'info>, - } - - impl<'info, 'entrypoint, A> Deref for WithPrograms<'info, 'entrypoint, A> { - type Target = A; - - fn deref(&self) -> &Self::Target { - &self.account - } - } - - pub type SeahorseAccount<'info, 'entrypoint, A> = - WithPrograms<'info, 'entrypoint, Box>>; - - pub type SeahorseSigner<'info, 'entrypoint> = WithPrograms<'info, 'entrypoint, Signer<'info>>; - - #[derive(Clone, Debug)] - pub struct CpiAccount<'info> { - #[doc = "CHECK: CpiAccounts temporarily store AccountInfos."] - pub account_info: AccountInfo<'info>, - pub is_writable: bool, - pub is_signer: bool, - pub seeds: Option>>, - } - - #[macro_export] - macro_rules! seahorse_const { - ($ name : ident , $ value : expr) => { - macro_rules! $name { - () => { - $value - }; - } - - pub(crate) use $name; - }; - } - - pub trait Loadable { - type Loaded; - - fn load(stored: Self) -> Self::Loaded; - - fn store(loaded: Self::Loaded) -> Self; - } - - macro_rules! Loaded { - ($ name : ty) => { - <$name as Loadable>::Loaded - }; - } - - pub(crate) use Loaded; - - #[macro_export] - macro_rules! assign { - ($ lval : expr , $ rval : expr) => {{ - let temp = $rval; - - $lval = temp; - }}; - } - - #[macro_export] - macro_rules! index_assign { - ($ lval : expr , $ idx : expr , $ rval : expr) => { - let temp_rval = $rval; - let temp_idx = $idx; - - $lval[temp_idx] = temp_rval; - }; - } - - pub(crate) use assign; - - pub(crate) use index_assign; - - pub(crate) use seahorse_const; -} - -#[program] -mod event { - use super::*; - use seahorse_util::*; - use std::collections::HashMap; - - #[derive(Accounts)] - # [instruction (data : u8 , title : String)] - pub struct SendEvent<'info> { - #[account(mut)] - pub sender: Signer<'info>, - } - - pub fn send_event(ctx: Context, data: u8, title: String) -> Result<()> { - let mut programs = HashMap::new(); - let programs_map = ProgramsMap(programs); - let sender = SeahorseSigner { - account: &ctx.accounts.sender, - programs: &programs_map, - }; - - send_event_handler(sender.clone(), data, title); - - return Ok(()); - } -} - diff --git a/tests/compiled-examples/fizzbuzz.rs b/tests/compiled-examples/fizzbuzz.rs index a0d3a7a..e69de29 100644 --- a/tests/compiled-examples/fizzbuzz.rs +++ b/tests/compiled-examples/fizzbuzz.rs @@ -1,370 +0,0 @@ -// ===== dot/mod.rs ===== - -pub mod program; - -// ===== dot/program.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] -use crate::{id, seahorse_util::*}; -use anchor_lang::{prelude::*, solana_program}; -use anchor_spl::token::{self, Mint, Token, TokenAccount}; -use std::{cell::RefCell, rc::Rc}; - -#[account] -#[derive(Debug)] -pub struct FizzBuzz { - pub fizz: bool, - pub buzz: bool, - pub n: u64, -} - -impl<'info, 'entrypoint> FizzBuzz { - pub fn load( - account: &'entrypoint mut Box>, - programs_map: &'entrypoint ProgramsMap<'info>, - ) -> Mutable> { - let fizz = account.fizz.clone(); - let buzz = account.buzz.clone(); - let n = account.n; - - Mutable::new(LoadedFizzBuzz { - __account__: account, - __programs__: programs_map, - fizz, - buzz, - n, - }) - } - - pub fn store(loaded: Mutable) { - let mut loaded = loaded.borrow_mut(); - let fizz = loaded.fizz.clone(); - - loaded.__account__.fizz = fizz; - - let buzz = loaded.buzz.clone(); - - loaded.__account__.buzz = buzz; - - let n = loaded.n; - - loaded.__account__.n = n; - } -} - -#[derive(Debug)] -pub struct LoadedFizzBuzz<'info, 'entrypoint> { - pub __account__: &'entrypoint mut Box>, - pub __programs__: &'entrypoint ProgramsMap<'info>, - pub fizz: bool, - pub buzz: bool, - pub n: u64, -} - -pub fn do_fizzbuzz_handler<'info>( - mut fizzbuzz: Mutable>, - mut n: u64, -) -> () { - assign!(fizzbuzz.borrow_mut().fizz, (n % 3) == 0); - - assign!(fizzbuzz.borrow_mut().buzz, (n % 5) == 0); - - if (!fizzbuzz.borrow().fizz) && (!fizzbuzz.borrow().buzz) { - assign!(fizzbuzz.borrow_mut().n, n); - } else { - assign!(fizzbuzz.borrow_mut().n, 0); - } -} - -pub fn init_handler<'info>( - mut owner: SeahorseSigner<'info, '_>, - mut fizzbuzz: Empty>>, -) -> () { - fizzbuzz.account.clone(); -} - -// ===== lib.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] - -pub mod dot; - -use anchor_lang::prelude::*; -use anchor_spl::{ - associated_token::{self, AssociatedToken}, - token::{self, Mint, Token, TokenAccount}, -}; - -use dot::program::*; -use std::{cell::RefCell, rc::Rc}; - -declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); - -pub mod seahorse_util { - use super::*; - use std::{ - collections::HashMap, - fmt::Debug, - ops::{Deref, Index, IndexMut}, - }; - - pub struct Mutable(Rc>); - - impl Mutable { - pub fn new(obj: T) -> Self { - Self(Rc::new(RefCell::new(obj))) - } - } - - impl Clone for Mutable { - fn clone(&self) -> Self { - Self(self.0.clone()) - } - } - - impl Deref for Mutable { - type Target = Rc>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - impl Debug for Mutable { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - - impl Default for Mutable { - fn default() -> Self { - Self::new(T::default()) - } - } - - pub trait IndexWrapped { - type Output; - - fn index_wrapped(&self, index: i128) -> &Self::Output; - } - - pub trait IndexWrappedMut: IndexWrapped { - fn index_wrapped_mut(&mut self, index: i128) -> &mut ::Output; - } - - impl IndexWrapped for Vec { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for Vec { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - impl IndexWrapped for [T; N] { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for [T; N] { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - #[derive(Clone)] - pub struct Empty { - pub account: T, - pub bump: Option, - } - - #[derive(Clone, Debug)] - pub struct ProgramsMap<'info>(pub HashMap<&'static str, AccountInfo<'info>>); - - impl<'info> ProgramsMap<'info> { - pub fn get(&self, name: &'static str) -> AccountInfo<'info> { - self.0.get(name).unwrap().clone() - } - } - - #[derive(Clone, Debug)] - pub struct WithPrograms<'info, 'entrypoint, A> { - pub account: &'entrypoint A, - pub programs: &'entrypoint ProgramsMap<'info>, - } - - impl<'info, 'entrypoint, A> Deref for WithPrograms<'info, 'entrypoint, A> { - type Target = A; - - fn deref(&self) -> &Self::Target { - &self.account - } - } - - pub type SeahorseAccount<'info, 'entrypoint, A> = - WithPrograms<'info, 'entrypoint, Box>>; - - pub type SeahorseSigner<'info, 'entrypoint> = WithPrograms<'info, 'entrypoint, Signer<'info>>; - - #[derive(Clone, Debug)] - pub struct CpiAccount<'info> { - #[doc = "CHECK: CpiAccounts temporarily store AccountInfos."] - pub account_info: AccountInfo<'info>, - pub is_writable: bool, - pub is_signer: bool, - pub seeds: Option>>, - } - - #[macro_export] - macro_rules! seahorse_const { - ($ name : ident , $ value : expr) => { - macro_rules! $name { - () => { - $value - }; - } - - pub(crate) use $name; - }; - } - - pub trait Loadable { - type Loaded; - - fn load(stored: Self) -> Self::Loaded; - - fn store(loaded: Self::Loaded) -> Self; - } - - macro_rules! Loaded { - ($ name : ty) => { - <$name as Loadable>::Loaded - }; - } - - pub(crate) use Loaded; - - #[macro_export] - macro_rules! assign { - ($ lval : expr , $ rval : expr) => {{ - let temp = $rval; - - $lval = temp; - }}; - } - - #[macro_export] - macro_rules! index_assign { - ($ lval : expr , $ idx : expr , $ rval : expr) => { - let temp_rval = $rval; - let temp_idx = $idx; - - $lval[temp_idx] = temp_rval; - }; - } - - pub(crate) use assign; - - pub(crate) use index_assign; - - pub(crate) use seahorse_const; -} - -#[program] -mod fizzbuzz { - use super::*; - use seahorse_util::*; - use std::collections::HashMap; - - #[derive(Accounts)] - # [instruction (n : u64)] - pub struct DoFizzbuzz<'info> { - #[account(mut)] - pub fizzbuzz: Box>, - } - - pub fn do_fizzbuzz(ctx: Context, n: u64) -> Result<()> { - let mut programs = HashMap::new(); - let programs_map = ProgramsMap(programs); - let fizzbuzz = dot::program::FizzBuzz::load(&mut ctx.accounts.fizzbuzz, &programs_map); - - do_fizzbuzz_handler(fizzbuzz.clone(), n); - - dot::program::FizzBuzz::store(fizzbuzz); - - return Ok(()); - } - - #[derive(Accounts)] - pub struct Init<'info> { - #[account(mut)] - pub owner: Signer<'info>, - # [account (init , space = std :: mem :: size_of :: < dot :: program :: FizzBuzz > () + 8 , payer = owner , seeds = ["fizzbuzz" . as_bytes () . as_ref () , owner . key () . as_ref ()] , bump)] - pub fizzbuzz: Box>, - pub rent: Sysvar<'info, Rent>, - pub system_program: Program<'info, System>, - } - - pub fn init(ctx: Context) -> Result<()> { - let mut programs = HashMap::new(); - - programs.insert( - "system_program", - ctx.accounts.system_program.to_account_info(), - ); - - let programs_map = ProgramsMap(programs); - let owner = SeahorseSigner { - account: &ctx.accounts.owner, - programs: &programs_map, - }; - - let fizzbuzz = Empty { - account: dot::program::FizzBuzz::load(&mut ctx.accounts.fizzbuzz, &programs_map), - bump: Some(ctx.bumps.fizzbuzz), - }; - - init_handler(owner.clone(), fizzbuzz.clone()); - - dot::program::FizzBuzz::store(fizzbuzz.account); - - return Ok(()); - } -} - diff --git a/tests/compiled-examples/hello.rs b/tests/compiled-examples/hello.rs index 484bf4a..e69de29 100644 --- a/tests/compiled-examples/hello.rs +++ b/tests/compiled-examples/hello.rs @@ -1,409 +0,0 @@ -// ===== dot/mod.rs ===== - -pub mod program; - -// ===== dot/program.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] -use crate::{id, seahorse_util::*}; -use anchor_lang::{prelude::*, solana_program}; -use anchor_spl::token::{self, Mint, Token, TokenAccount}; -use std::{cell::RefCell, rc::Rc}; - -#[account] -#[derive(Debug)] -pub struct Hello { - pub bump: u8, -} - -impl<'info, 'entrypoint> Hello { - pub fn load( - account: &'entrypoint mut Box>, - programs_map: &'entrypoint ProgramsMap<'info>, - ) -> Mutable> { - let bump = account.bump; - - Mutable::new(LoadedHello { - __account__: account, - __programs__: programs_map, - bump, - }) - } - - pub fn store(loaded: Mutable) { - let mut loaded = loaded.borrow_mut(); - let bump = loaded.bump; - - loaded.__account__.bump = bump; - } -} - -#[derive(Debug)] -pub struct LoadedHello<'info, 'entrypoint> { - pub __account__: &'entrypoint mut Box>, - pub __programs__: &'entrypoint ProgramsMap<'info>, - pub bump: u8, -} - -pub fn init_handler<'info>( - mut owner: SeahorseSigner<'info, '_>, - mut hello: Empty>>, - mut mint: Empty>, -) -> () { - let mut bump = hello.bump.unwrap(); - let mut hello = hello.account.clone(); - - mint.account.clone(); - - assign!(hello.borrow_mut().bump, bump); -} - -pub fn say_hello_handler<'info>( - mut user_acc: SeahorseAccount<'info, '_, TokenAccount>, - mut hello: Mutable>, - mut mint: SeahorseAccount<'info, '_, Mint>, -) -> () { - let mut bump = hello.borrow().bump; - - solana_program::msg!("{}", format!("Hello {:?}, have a token!", user_acc.owner)); - - token::mint_to( - CpiContext::new_with_signer( - mint.programs.get("token_program"), - token::MintTo { - mint: mint.to_account_info(), - authority: hello.borrow().__account__.to_account_info(), - to: user_acc.clone().to_account_info(), - }, - &[Mutable::new(vec![ - "hello".to_string().as_bytes().as_ref(), - bump.to_le_bytes().as_ref(), - ]) - .borrow() - .as_slice()], - ), - >::try_from(1).unwrap(), - ) - .unwrap(); -} - -// ===== lib.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] - -pub mod dot; - -use anchor_lang::prelude::*; -use anchor_spl::{ - associated_token::{self, AssociatedToken}, - token::{self, Mint, Token, TokenAccount}, -}; - -use dot::program::*; -use std::{cell::RefCell, rc::Rc}; - -declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); - -pub mod seahorse_util { - use super::*; - use std::{ - collections::HashMap, - fmt::Debug, - ops::{Deref, Index, IndexMut}, - }; - - pub struct Mutable(Rc>); - - impl Mutable { - pub fn new(obj: T) -> Self { - Self(Rc::new(RefCell::new(obj))) - } - } - - impl Clone for Mutable { - fn clone(&self) -> Self { - Self(self.0.clone()) - } - } - - impl Deref for Mutable { - type Target = Rc>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - impl Debug for Mutable { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - - impl Default for Mutable { - fn default() -> Self { - Self::new(T::default()) - } - } - - pub trait IndexWrapped { - type Output; - - fn index_wrapped(&self, index: i128) -> &Self::Output; - } - - pub trait IndexWrappedMut: IndexWrapped { - fn index_wrapped_mut(&mut self, index: i128) -> &mut ::Output; - } - - impl IndexWrapped for Vec { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for Vec { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - impl IndexWrapped for [T; N] { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for [T; N] { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - #[derive(Clone)] - pub struct Empty { - pub account: T, - pub bump: Option, - } - - #[derive(Clone, Debug)] - pub struct ProgramsMap<'info>(pub HashMap<&'static str, AccountInfo<'info>>); - - impl<'info> ProgramsMap<'info> { - pub fn get(&self, name: &'static str) -> AccountInfo<'info> { - self.0.get(name).unwrap().clone() - } - } - - #[derive(Clone, Debug)] - pub struct WithPrograms<'info, 'entrypoint, A> { - pub account: &'entrypoint A, - pub programs: &'entrypoint ProgramsMap<'info>, - } - - impl<'info, 'entrypoint, A> Deref for WithPrograms<'info, 'entrypoint, A> { - type Target = A; - - fn deref(&self) -> &Self::Target { - &self.account - } - } - - pub type SeahorseAccount<'info, 'entrypoint, A> = - WithPrograms<'info, 'entrypoint, Box>>; - - pub type SeahorseSigner<'info, 'entrypoint> = WithPrograms<'info, 'entrypoint, Signer<'info>>; - - #[derive(Clone, Debug)] - pub struct CpiAccount<'info> { - #[doc = "CHECK: CpiAccounts temporarily store AccountInfos."] - pub account_info: AccountInfo<'info>, - pub is_writable: bool, - pub is_signer: bool, - pub seeds: Option>>, - } - - #[macro_export] - macro_rules! seahorse_const { - ($ name : ident , $ value : expr) => { - macro_rules! $name { - () => { - $value - }; - } - - pub(crate) use $name; - }; - } - - pub trait Loadable { - type Loaded; - - fn load(stored: Self) -> Self::Loaded; - - fn store(loaded: Self::Loaded) -> Self; - } - - macro_rules! Loaded { - ($ name : ty) => { - <$name as Loadable>::Loaded - }; - } - - pub(crate) use Loaded; - - #[macro_export] - macro_rules! assign { - ($ lval : expr , $ rval : expr) => {{ - let temp = $rval; - - $lval = temp; - }}; - } - - #[macro_export] - macro_rules! index_assign { - ($ lval : expr , $ idx : expr , $ rval : expr) => { - let temp_rval = $rval; - let temp_idx = $idx; - - $lval[temp_idx] = temp_rval; - }; - } - - pub(crate) use assign; - - pub(crate) use index_assign; - - pub(crate) use seahorse_const; -} - -#[program] -mod hello { - use super::*; - use seahorse_util::*; - use std::collections::HashMap; - - #[derive(Accounts)] - pub struct Init<'info> { - #[account(mut)] - pub owner: Signer<'info>, - # [account (init , space = std :: mem :: size_of :: < dot :: program :: Hello > () + 8 , payer = owner , seeds = ["hello" . as_bytes () . as_ref ()] , bump)] - pub hello: Box>, - # [account (init , payer = owner , seeds = ["hello-mint" . as_bytes () . as_ref ()] , bump , mint :: decimals = 0 , mint :: authority = hello)] - pub mint: Box>, - pub rent: Sysvar<'info, Rent>, - pub system_program: Program<'info, System>, - pub token_program: Program<'info, Token>, - } - - pub fn init(ctx: Context) -> Result<()> { - let mut programs = HashMap::new(); - - programs.insert( - "system_program", - ctx.accounts.system_program.to_account_info(), - ); - - programs.insert( - "token_program", - ctx.accounts.token_program.to_account_info(), - ); - - let programs_map = ProgramsMap(programs); - let owner = SeahorseSigner { - account: &ctx.accounts.owner, - programs: &programs_map, - }; - - let hello = Empty { - account: dot::program::Hello::load(&mut ctx.accounts.hello, &programs_map), - bump: Some(ctx.bumps.hello), - }; - - let mint = Empty { - account: SeahorseAccount { - account: &ctx.accounts.mint, - programs: &programs_map, - }, - bump: Some(ctx.bumps.mint), - }; - - init_handler(owner.clone(), hello.clone(), mint.clone()); - - dot::program::Hello::store(hello.account); - - return Ok(()); - } - - #[derive(Accounts)] - pub struct SayHello<'info> { - #[account(mut)] - pub user_acc: Box>, - #[account(mut)] - pub hello: Box>, - #[account(mut)] - pub mint: Box>, - pub token_program: Program<'info, Token>, - } - - pub fn say_hello(ctx: Context) -> Result<()> { - let mut programs = HashMap::new(); - - programs.insert( - "token_program", - ctx.accounts.token_program.to_account_info(), - ); - - let programs_map = ProgramsMap(programs); - let user_acc = SeahorseAccount { - account: &ctx.accounts.user_acc, - programs: &programs_map, - }; - - let hello = dot::program::Hello::load(&mut ctx.accounts.hello, &programs_map); - let mint = SeahorseAccount { - account: &ctx.accounts.mint, - programs: &programs_map, - }; - - say_hello_handler(user_acc.clone(), hello.clone(), mint.clone()); - - dot::program::Hello::store(hello); - - return Ok(()); - } -} - diff --git a/tests/compiled-examples/pyth.rs b/tests/compiled-examples/pyth.rs index 5f326cf..e69de29 100644 --- a/tests/compiled-examples/pyth.rs +++ b/tests/compiled-examples/pyth.rs @@ -1,286 +0,0 @@ -// ===== dot/mod.rs ===== - -pub mod program; - -// ===== dot/program.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] -use crate::{id, seahorse_util::*}; -use anchor_lang::{prelude::*, solana_program}; -use anchor_spl::token::{self, Mint, Token, TokenAccount}; -use std::{cell::RefCell, rc::Rc}; - -pub fn use_sol_usd_price_handler<'info>(mut price_account: UncheckedAccount<'info>) -> () { - let mut price_feed = { - if price_account.key() - != Pubkey::new_from_array([ - 254u8, 101u8, 15u8, 3u8, 103u8, 212u8, 167u8, 239u8, 152u8, 21u8, 165u8, 147u8, - 234u8, 21u8, 211u8, 101u8, 147u8, 240u8, 100u8, 58u8, 170u8, 240u8, 20u8, 155u8, - 176u8, 75u8, 230u8, 122u8, 184u8, 81u8, 222u8, 205u8, - ]) - { - panic!("Pyth PriceAccount validation failed: expected devnet-SOL/USD") - } - - load_price_feed_from_account_info(&price_account).unwrap() - }; - - let mut price = price_feed.get_price_unchecked(); - let mut price = { - let price = price; - - (price.price as f64) * 10f64.powf(price.expo as f64) - }; - - solana_program::msg!("{}", price); -} - -// ===== lib.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] - -pub mod dot; - -use anchor_lang::prelude::*; -use anchor_spl::{ - associated_token::{self, AssociatedToken}, - token::{self, Mint, Token, TokenAccount}, -}; - -use dot::program::*; -use std::{cell::RefCell, rc::Rc}; - -declare_id!("EkY7qZD2RCr1LpUzADJkzbjGaWfbvGYB9eJe7DYCgGF8"); - -pub mod seahorse_util { - use super::*; - - pub use pyth_sdk_solana::{load_price_feed_from_account_info, PriceFeed}; - use std::{ - collections::HashMap, - fmt::Debug, - ops::{Deref, Index, IndexMut}, - }; - - pub struct Mutable(Rc>); - - impl Mutable { - pub fn new(obj: T) -> Self { - Self(Rc::new(RefCell::new(obj))) - } - } - - impl Clone for Mutable { - fn clone(&self) -> Self { - Self(self.0.clone()) - } - } - - impl Deref for Mutable { - type Target = Rc>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - impl Debug for Mutable { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - - impl Default for Mutable { - fn default() -> Self { - Self::new(T::default()) - } - } - - pub trait IndexWrapped { - type Output; - - fn index_wrapped(&self, index: i128) -> &Self::Output; - } - - pub trait IndexWrappedMut: IndexWrapped { - fn index_wrapped_mut(&mut self, index: i128) -> &mut ::Output; - } - - impl IndexWrapped for Vec { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for Vec { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - impl IndexWrapped for [T; N] { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for [T; N] { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - #[derive(Clone)] - pub struct Empty { - pub account: T, - pub bump: Option, - } - - #[derive(Clone, Debug)] - pub struct ProgramsMap<'info>(pub HashMap<&'static str, AccountInfo<'info>>); - - impl<'info> ProgramsMap<'info> { - pub fn get(&self, name: &'static str) -> AccountInfo<'info> { - self.0.get(name).unwrap().clone() - } - } - - #[derive(Clone, Debug)] - pub struct WithPrograms<'info, 'entrypoint, A> { - pub account: &'entrypoint A, - pub programs: &'entrypoint ProgramsMap<'info>, - } - - impl<'info, 'entrypoint, A> Deref for WithPrograms<'info, 'entrypoint, A> { - type Target = A; - - fn deref(&self) -> &Self::Target { - &self.account - } - } - - pub type SeahorseAccount<'info, 'entrypoint, A> = - WithPrograms<'info, 'entrypoint, Box>>; - - pub type SeahorseSigner<'info, 'entrypoint> = WithPrograms<'info, 'entrypoint, Signer<'info>>; - - #[derive(Clone, Debug)] - pub struct CpiAccount<'info> { - #[doc = "CHECK: CpiAccounts temporarily store AccountInfos."] - pub account_info: AccountInfo<'info>, - pub is_writable: bool, - pub is_signer: bool, - pub seeds: Option>>, - } - - #[macro_export] - macro_rules! seahorse_const { - ($ name : ident , $ value : expr) => { - macro_rules! $name { - () => { - $value - }; - } - - pub(crate) use $name; - }; - } - - pub trait Loadable { - type Loaded; - - fn load(stored: Self) -> Self::Loaded; - - fn store(loaded: Self::Loaded) -> Self; - } - - macro_rules! Loaded { - ($ name : ty) => { - <$name as Loadable>::Loaded - }; - } - - pub(crate) use Loaded; - - #[macro_export] - macro_rules! assign { - ($ lval : expr , $ rval : expr) => {{ - let temp = $rval; - - $lval = temp; - }}; - } - - #[macro_export] - macro_rules! index_assign { - ($ lval : expr , $ idx : expr , $ rval : expr) => { - let temp_rval = $rval; - let temp_idx = $idx; - - $lval[temp_idx] = temp_rval; - }; - } - - pub(crate) use assign; - - pub(crate) use index_assign; - - pub(crate) use seahorse_const; -} - -#[program] -mod pyth { - use super::*; - use seahorse_util::*; - use std::collections::HashMap; - - #[derive(Accounts)] - pub struct UseSolUsdPrice<'info> { - #[account()] - #[doc = "CHECK: This account is unchecked."] - pub price_account: UncheckedAccount<'info>, - } - - pub fn use_sol_usd_price(ctx: Context) -> Result<()> { - let mut programs = HashMap::new(); - let programs_map = ProgramsMap(programs); - let price_account = &ctx.accounts.price_account.clone(); - - use_sol_usd_price_handler(price_account.clone()); - - return Ok(()); - } -} - diff --git a/tests/compiled-examples/stored_mutables.rs b/tests/compiled-examples/stored_mutables.rs index d971f77..e69de29 100644 --- a/tests/compiled-examples/stored_mutables.rs +++ b/tests/compiled-examples/stored_mutables.rs @@ -1,742 +0,0 @@ -// ===== dot/mod.rs ===== - -pub mod program; - -pub mod util; - -// ===== dot/program.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] -use crate::dot::util::more_data::MoreData; -use crate::{id, seahorse_util::*}; -use anchor_lang::{prelude::*, solana_program}; -use anchor_spl::token::{self, Mint, Token, TokenAccount}; -use std::{cell::RefCell, rc::Rc}; - -#[account] -#[derive(Debug)] -pub struct Data { - pub array_2d: [[i32; 2]; 2], - pub int_list: Vec, - pub int_list_2d: Vec>, - pub string: String, - pub nested: Nested, - pub nested_list: Vec, - pub flag: Flag, - pub more_data: MoreData, -} - -impl<'info, 'entrypoint> Data { - pub fn load( - account: &'entrypoint mut Box>, - programs_map: &'entrypoint ProgramsMap<'info>, - ) -> Mutable> { - let array_2d = Mutable::new( - account - .array_2d - .clone() - .map(|element| Mutable::new(element.map(|element| element))), - ); - - let int_list = Mutable::new( - account - .int_list - .clone() - .into_iter() - .map(|element| element) - .collect(), - ); - - let int_list_2d = Mutable::new( - account - .int_list_2d - .clone() - .into_iter() - .map(|element| Mutable::new(element.into_iter().map(|element| element).collect())) - .collect(), - ); - - let string = account.string.clone(); - let nested = Mutable::new(Nested::load(account.nested.clone())); - let nested_list = Mutable::new( - account - .nested_list - .clone() - .into_iter() - .map(|element| Mutable::new(Nested::load(element))) - .collect(), - ); - - let flag = account.flag.clone(); - let more_data = Mutable::new(MoreData::load(account.more_data.clone())); - - Mutable::new(LoadedData { - __account__: account, - __programs__: programs_map, - array_2d, - int_list, - int_list_2d, - string, - nested, - nested_list, - flag, - more_data, - }) - } - - pub fn store(loaded: Mutable) { - let mut loaded = loaded.borrow_mut(); - let array_2d = loaded - .array_2d - .clone() - .borrow() - .clone() - .map(|element| element.borrow().clone().map(|element| element)); - - loaded.__account__.array_2d = array_2d; - - let int_list = loaded - .int_list - .clone() - .borrow() - .clone() - .into_iter() - .map(|element| element) - .collect(); - - loaded.__account__.int_list = int_list; - - let int_list_2d = loaded - .int_list_2d - .clone() - .borrow() - .clone() - .into_iter() - .map(|element| { - element - .borrow() - .clone() - .into_iter() - .map(|element| element) - .collect() - }) - .collect(); - - loaded.__account__.int_list_2d = int_list_2d; - - let string = loaded.string.clone(); - - loaded.__account__.string = string; - - let nested = Nested::store(loaded.nested.clone().borrow().clone()); - - loaded.__account__.nested = nested; - - let nested_list = loaded - .nested_list - .clone() - .borrow() - .clone() - .into_iter() - .map(|element| Nested::store(element.borrow().clone())) - .collect(); - - loaded.__account__.nested_list = nested_list; - - let flag = loaded.flag.clone(); - - loaded.__account__.flag = flag; - - let more_data = MoreData::store(loaded.more_data.clone().borrow().clone()); - - loaded.__account__.more_data = more_data; - } -} - -#[derive(Debug)] -pub struct LoadedData<'info, 'entrypoint> { - pub __account__: &'entrypoint mut Box>, - pub __programs__: &'entrypoint ProgramsMap<'info>, - pub array_2d: Mutable<[Mutable<[i32; 2]>; 2]>, - pub int_list: Mutable>, - pub int_list_2d: Mutable>>>, - pub string: String, - pub nested: Mutable, - pub nested_list: Mutable>>, - pub flag: Flag, - pub more_data: Mutable, -} - -#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)] -pub struct Deep { - pub num: i32, -} - -#[derive(Clone, Debug, Default)] -pub struct LoadedDeep { - pub num: i32, -} - -impl Mutable { - pub fn __init__(&self, mut num: i32) -> () { - assign!(self.borrow_mut().num, num); - } -} - -impl LoadedDeep { - pub fn __new__(num: i32) -> Mutable { - let obj = Mutable::new(LoadedDeep::default()); - - obj.__init__(num); - - return obj; - } -} - -impl Loadable for Deep { - type Loaded = LoadedDeep; - - fn load(stored: Self) -> Self::Loaded { - Self::Loaded { num: stored.num } - } - - fn store(loaded: Self::Loaded) -> Self { - Self { num: loaded.num } - } -} - -#[derive(Clone, Debug, PartialEq, AnchorSerialize, AnchorDeserialize, Copy)] -pub enum Flag { - OFF, - ON, -} - -impl Default for Flag { - fn default() -> Self { - Flag::OFF - } -} - -#[event] -pub struct MyEvent { - pub nums: Vec, -} - -#[derive(Clone, Debug, Default)] -pub struct LoadedMyEvent { - pub nums: Mutable>, -} - -impl Mutable { - fn __emit__(&self) { - let e = self.borrow(); - - emit!(MyEvent { - nums: e - .nums - .clone() - .borrow() - .clone() - .into_iter() - .map(|element| element) - .collect() - }) - } -} - -impl Loadable for MyEvent { - type Loaded = LoadedMyEvent; - - fn load(stored: Self) -> Self::Loaded { - Self::Loaded { - nums: Mutable::new(stored.nums.into_iter().map(|element| element).collect()), - } - } - - fn store(loaded: Self::Loaded) -> Self { - Self { - nums: loaded - .nums - .clone() - .borrow() - .clone() - .into_iter() - .map(|element| element) - .collect(), - } - } -} - -#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)] -pub struct Nested { - pub deep: Deep, -} - -#[derive(Clone, Debug, Default)] -pub struct LoadedNested { - pub deep: Mutable, -} - -impl Mutable { - pub fn __init__(&self, mut num: i32) -> () { - assign!( - self.borrow_mut().deep, - ::__new__(num.clone()) - ); - } - - pub fn reset(&self) -> () { - assign!(self.borrow_mut().deep, ::__new__(0)); - } -} - -impl LoadedNested { - pub fn __new__(num: i32) -> Mutable { - let obj = Mutable::new(LoadedNested::default()); - - obj.__init__(num); - - return obj; - } -} - -impl Loadable for Nested { - type Loaded = LoadedNested; - - fn load(stored: Self) -> Self::Loaded { - Self::Loaded { - deep: Mutable::new(Deep::load(stored.deep)), - } - } - - fn store(loaded: Self::Loaded) -> Self { - Self { - deep: Deep::store(loaded.deep.clone().borrow().clone()), - } - } -} - -pub fn init_handler<'info>( - mut signer: SeahorseSigner<'info, '_>, - mut data: Empty>>, -) -> () { - let mut init_data = data.account.clone(); - - assign!(init_data.borrow_mut().int_list, Mutable::new(vec![1, 2])); - - assign!( - init_data.borrow_mut().int_list_2d, - Mutable::new(vec![Mutable::new(vec![3, 4]), Mutable::new(vec![5, 6])]) - ); - - assign!(init_data.borrow_mut().string, "Hello".to_string()); - - assign!(init_data.borrow_mut().nested, ::__new__(7)); - - assign!( - init_data.borrow_mut().nested_list, - Mutable::new(vec![ - ::__new__(8), - ::__new__(9) - ]) - ); - - assign!( - init_data.borrow_mut().more_data, - ::__new__(10) - ); -} - -pub fn test_stored_mutables_handler<'info>( - mut signer: SeahorseSigner<'info, '_>, - mut data: Mutable>, -) -> () { - assign!( - (*(*data - .borrow_mut() - .array_2d - .borrow_mut() - .index_wrapped_mut(0.into())) - .borrow_mut() - .index_wrapped_mut(0.into())), - 1 - ); - - data.borrow().int_list.borrow_mut().push(0); - - assign!( - (*(*data - .borrow_mut() - .int_list_2d - .borrow_mut() - .index_wrapped_mut(0.into())) - .borrow_mut() - .index_wrapped_mut((-1).into())), - 0 - ); - - assign!( - data.borrow_mut().string, - data.borrow().string.clone() + &" World".to_string() - ); - - data.borrow().nested.reset(); - - (*data.borrow().nested_list.borrow().index_wrapped(0.into())).reset(); - - data.borrow() - .nested_list - .borrow_mut() - .push(::__new__(10)); - - assign!(data.borrow_mut().flag, Flag::ON); - - assign!( - data.borrow_mut().more_data, - ::__new__(11) - ); -} - -// ===== dot/util/mod.rs ===== - -pub mod more_data; - -// ===== dot/util/more_data.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] -use crate::{id, seahorse_util::*}; -use anchor_lang::{prelude::*, solana_program}; -use anchor_spl::token::{self, Mint, Token, TokenAccount}; -use std::{cell::RefCell, rc::Rc}; - -#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)] -pub struct MoreData { - pub num: i32, -} - -#[derive(Clone, Debug, Default)] -pub struct LoadedMoreData { - pub num: i32, -} - -impl Mutable { - pub fn __init__(&self, mut num: i32) -> () { - assign!(self.borrow_mut().num, num); - } -} - -impl LoadedMoreData { - pub fn __new__(num: i32) -> Mutable { - let obj = Mutable::new(LoadedMoreData::default()); - - obj.__init__(num); - - return obj; - } -} - -impl Loadable for MoreData { - type Loaded = LoadedMoreData; - - fn load(stored: Self) -> Self::Loaded { - Self::Loaded { num: stored.num } - } - - fn store(loaded: Self::Loaded) -> Self { - Self { num: loaded.num } - } -} - -// ===== lib.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] - -pub mod dot; - -use anchor_lang::prelude::*; -use anchor_spl::{ - associated_token::{self, AssociatedToken}, - token::{self, Mint, Token, TokenAccount}, -}; - -use dot::program::*; -use std::{cell::RefCell, rc::Rc}; - -declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); - -pub mod seahorse_util { - use super::*; - use std::{ - collections::HashMap, - fmt::Debug, - ops::{Deref, Index, IndexMut}, - }; - - pub struct Mutable(Rc>); - - impl Mutable { - pub fn new(obj: T) -> Self { - Self(Rc::new(RefCell::new(obj))) - } - } - - impl Clone for Mutable { - fn clone(&self) -> Self { - Self(self.0.clone()) - } - } - - impl Deref for Mutable { - type Target = Rc>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - impl Debug for Mutable { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - - impl Default for Mutable { - fn default() -> Self { - Self::new(T::default()) - } - } - - pub trait IndexWrapped { - type Output; - - fn index_wrapped(&self, index: i128) -> &Self::Output; - } - - pub trait IndexWrappedMut: IndexWrapped { - fn index_wrapped_mut(&mut self, index: i128) -> &mut ::Output; - } - - impl IndexWrapped for Vec { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for Vec { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - impl IndexWrapped for [T; N] { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for [T; N] { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - #[derive(Clone)] - pub struct Empty { - pub account: T, - pub bump: Option, - } - - #[derive(Clone, Debug)] - pub struct ProgramsMap<'info>(pub HashMap<&'static str, AccountInfo<'info>>); - - impl<'info> ProgramsMap<'info> { - pub fn get(&self, name: &'static str) -> AccountInfo<'info> { - self.0.get(name).unwrap().clone() - } - } - - #[derive(Clone, Debug)] - pub struct WithPrograms<'info, 'entrypoint, A> { - pub account: &'entrypoint A, - pub programs: &'entrypoint ProgramsMap<'info>, - } - - impl<'info, 'entrypoint, A> Deref for WithPrograms<'info, 'entrypoint, A> { - type Target = A; - - fn deref(&self) -> &Self::Target { - &self.account - } - } - - pub type SeahorseAccount<'info, 'entrypoint, A> = - WithPrograms<'info, 'entrypoint, Box>>; - - pub type SeahorseSigner<'info, 'entrypoint> = WithPrograms<'info, 'entrypoint, Signer<'info>>; - - #[derive(Clone, Debug)] - pub struct CpiAccount<'info> { - #[doc = "CHECK: CpiAccounts temporarily store AccountInfos."] - pub account_info: AccountInfo<'info>, - pub is_writable: bool, - pub is_signer: bool, - pub seeds: Option>>, - } - - #[macro_export] - macro_rules! seahorse_const { - ($ name : ident , $ value : expr) => { - macro_rules! $name { - () => { - $value - }; - } - - pub(crate) use $name; - }; - } - - pub trait Loadable { - type Loaded; - - fn load(stored: Self) -> Self::Loaded; - - fn store(loaded: Self::Loaded) -> Self; - } - - macro_rules! Loaded { - ($ name : ty) => { - <$name as Loadable>::Loaded - }; - } - - pub(crate) use Loaded; - - #[macro_export] - macro_rules! assign { - ($ lval : expr , $ rval : expr) => {{ - let temp = $rval; - - $lval = temp; - }}; - } - - #[macro_export] - macro_rules! index_assign { - ($ lval : expr , $ idx : expr , $ rval : expr) => { - let temp_rval = $rval; - let temp_idx = $idx; - - $lval[temp_idx] = temp_rval; - }; - } - - pub(crate) use assign; - - pub(crate) use index_assign; - - pub(crate) use seahorse_const; -} - -#[program] -mod stored_mutables { - use super::*; - use seahorse_util::*; - use std::collections::HashMap; - - #[derive(Accounts)] - pub struct Init<'info> { - #[account(mut)] - pub signer: Signer<'info>, - # [account (init , space = std :: mem :: size_of :: < dot :: program :: Data > () + 8 + (1024 as usize) , payer = signer , seeds = [signer . key () . as_ref ()] , bump)] - pub data: Box>, - pub rent: Sysvar<'info, Rent>, - pub system_program: Program<'info, System>, - } - - pub fn init(ctx: Context) -> Result<()> { - let mut programs = HashMap::new(); - - programs.insert( - "system_program", - ctx.accounts.system_program.to_account_info(), - ); - - let programs_map = ProgramsMap(programs); - let signer = SeahorseSigner { - account: &ctx.accounts.signer, - programs: &programs_map, - }; - - let data = Empty { - account: dot::program::Data::load(&mut ctx.accounts.data, &programs_map), - bump: Some(ctx.bumps.data), - }; - - init_handler(signer.clone(), data.clone()); - - dot::program::Data::store(data.account); - - return Ok(()); - } - - #[derive(Accounts)] - pub struct TestStoredMutables<'info> { - #[account(mut)] - pub signer: Signer<'info>, - #[account(mut)] - pub data: Box>, - } - - pub fn test_stored_mutables(ctx: Context) -> Result<()> { - let mut programs = HashMap::new(); - let programs_map = ProgramsMap(programs); - let signer = SeahorseSigner { - account: &ctx.accounts.signer, - programs: &programs_map, - }; - - let data = dot::program::Data::load(&mut ctx.accounts.data, &programs_map); - - test_stored_mutables_handler(signer.clone(), data.clone()); - - dot::program::Data::store(data); - - return Ok(()); - } -} - diff --git a/tests/compiled-test-cases/account_key.rs b/tests/compiled-test-cases/account_key.rs index 4025740..e69de29 100644 --- a/tests/compiled-test-cases/account_key.rs +++ b/tests/compiled-test-cases/account_key.rs @@ -1,365 +0,0 @@ -// ===== dot/mod.rs ===== - -pub mod program; - -// ===== dot/program.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] -use crate::{id, seahorse_util::*}; -use anchor_lang::{prelude::*, solana_program}; -use anchor_spl::token::{self, Mint, Token, TokenAccount}; -use std::{cell::RefCell, rc::Rc}; - -#[account] -#[derive(Debug)] -pub struct Another { - pub data: u8, -} - -impl<'info, 'entrypoint> Another { - pub fn load( - account: &'entrypoint mut Box>, - programs_map: &'entrypoint ProgramsMap<'info>, - ) -> Mutable> { - let data = account.data; - - Mutable::new(LoadedAnother { - __account__: account, - __programs__: programs_map, - data, - }) - } - - pub fn store(loaded: Mutable) { - let mut loaded = loaded.borrow_mut(); - let data = loaded.data; - - loaded.__account__.data = data; - } -} - -#[derive(Debug)] -pub struct LoadedAnother<'info, 'entrypoint> { - pub __account__: &'entrypoint mut Box>, - pub __programs__: &'entrypoint ProgramsMap<'info>, - pub data: u8, -} - -#[account] -#[derive(Debug)] -pub struct User { - pub data: u8, -} - -impl<'info, 'entrypoint> User { - pub fn load( - account: &'entrypoint mut Box>, - programs_map: &'entrypoint ProgramsMap<'info>, - ) -> Mutable> { - let data = account.data; - - Mutable::new(LoadedUser { - __account__: account, - __programs__: programs_map, - data, - }) - } - - pub fn store(loaded: Mutable) { - let mut loaded = loaded.borrow_mut(); - let data = loaded.data; - - loaded.__account__.data = data; - } -} - -#[derive(Debug)] -pub struct LoadedUser<'info, 'entrypoint> { - pub __account__: &'entrypoint mut Box>, - pub __programs__: &'entrypoint ProgramsMap<'info>, - pub data: u8, -} - -pub fn ix_handler<'info>( - mut payer: SeahorseSigner<'info, '_>, - mut user: Mutable>, - mut another: Empty>>, -) -> () { - let mut a = another.account.clone(); - - solana_program::msg!("{:?}", user.borrow().__account__.key()); - - solana_program::msg!("{}", user.borrow().data); -} - -// ===== lib.rs ===== - -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] - -pub mod dot; - -use anchor_lang::prelude::*; -use anchor_spl::{ - associated_token::{self, AssociatedToken}, - token::{self, Mint, Token, TokenAccount}, -}; - -use dot::program::*; -use std::{cell::RefCell, rc::Rc}; - -declare_id!("4SEMJzX6o2YQNws7yrsfUdjJCR4B5Z3GyR2Pj7UgzDy2"); - -pub mod seahorse_util { - use super::*; - use std::{ - collections::HashMap, - fmt::Debug, - ops::{Deref, Index, IndexMut}, - }; - - pub struct Mutable(Rc>); - - impl Mutable { - pub fn new(obj: T) -> Self { - Self(Rc::new(RefCell::new(obj))) - } - } - - impl Clone for Mutable { - fn clone(&self) -> Self { - Self(self.0.clone()) - } - } - - impl Deref for Mutable { - type Target = Rc>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - impl Debug for Mutable { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - - impl Default for Mutable { - fn default() -> Self { - Self::new(T::default()) - } - } - - pub trait IndexWrapped { - type Output; - - fn index_wrapped(&self, index: i128) -> &Self::Output; - } - - pub trait IndexWrappedMut: IndexWrapped { - fn index_wrapped_mut(&mut self, index: i128) -> &mut ::Output; - } - - impl IndexWrapped for Vec { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for Vec { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += self.len() as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - impl IndexWrapped for [T; N] { - type Output = T; - - fn index_wrapped(&self, mut index: i128) -> &Self::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index(index) - } - } - - impl IndexWrappedMut for [T; N] { - fn index_wrapped_mut(&mut self, mut index: i128) -> &mut ::Output { - if index < 0 { - index += N as i128; - } - - let index: usize = index.try_into().unwrap(); - - self.index_mut(index) - } - } - - #[derive(Clone)] - pub struct Empty { - pub account: T, - pub bump: Option, - } - - #[derive(Clone, Debug)] - pub struct ProgramsMap<'info>(pub HashMap<&'static str, AccountInfo<'info>>); - - impl<'info> ProgramsMap<'info> { - pub fn get(&self, name: &'static str) -> AccountInfo<'info> { - self.0.get(name).unwrap().clone() - } - } - - #[derive(Clone, Debug)] - pub struct WithPrograms<'info, 'entrypoint, A> { - pub account: &'entrypoint A, - pub programs: &'entrypoint ProgramsMap<'info>, - } - - impl<'info, 'entrypoint, A> Deref for WithPrograms<'info, 'entrypoint, A> { - type Target = A; - - fn deref(&self) -> &Self::Target { - &self.account - } - } - - pub type SeahorseAccount<'info, 'entrypoint, A> = - WithPrograms<'info, 'entrypoint, Box>>; - - pub type SeahorseSigner<'info, 'entrypoint> = WithPrograms<'info, 'entrypoint, Signer<'info>>; - - #[derive(Clone, Debug)] - pub struct CpiAccount<'info> { - #[doc = "CHECK: CpiAccounts temporarily store AccountInfos."] - pub account_info: AccountInfo<'info>, - pub is_writable: bool, - pub is_signer: bool, - pub seeds: Option>>, - } - - #[macro_export] - macro_rules! seahorse_const { - ($ name : ident , $ value : expr) => { - macro_rules! $name { - () => { - $value - }; - } - - pub(crate) use $name; - }; - } - - pub trait Loadable { - type Loaded; - - fn load(stored: Self) -> Self::Loaded; - - fn store(loaded: Self::Loaded) -> Self; - } - - macro_rules! Loaded { - ($ name : ty) => { - <$name as Loadable>::Loaded - }; - } - - pub(crate) use Loaded; - - #[macro_export] - macro_rules! assign { - ($ lval : expr , $ rval : expr) => {{ - let temp = $rval; - - $lval = temp; - }}; - } - - #[macro_export] - macro_rules! index_assign { - ($ lval : expr , $ idx : expr , $ rval : expr) => { - let temp_rval = $rval; - let temp_idx = $idx; - - $lval[temp_idx] = temp_rval; - }; - } - - pub(crate) use assign; - - pub(crate) use index_assign; - - pub(crate) use seahorse_const; -} - -#[program] -mod account_key { - use super::*; - use seahorse_util::*; - use std::collections::HashMap; - - #[derive(Accounts)] - pub struct Ix<'info> { - #[account(mut)] - pub payer: Signer<'info>, - #[account(mut)] - pub user: Box>, - # [account (init , space = std :: mem :: size_of :: < dot :: program :: Another > () + 8 , payer = payer , seeds = [user . key () . as_ref ()] , bump)] - pub another: Box>, - pub rent: Sysvar<'info, Rent>, - pub system_program: Program<'info, System>, - } - - pub fn ix(ctx: Context) -> Result<()> { - let mut programs = HashMap::new(); - - programs.insert( - "system_program", - ctx.accounts.system_program.to_account_info(), - ); - - let programs_map = ProgramsMap(programs); - let payer = SeahorseSigner { - account: &ctx.accounts.payer, - programs: &programs_map, - }; - - let user = dot::program::User::load(&mut ctx.accounts.user, &programs_map); - let another = Empty { - account: dot::program::Another::load(&mut ctx.accounts.another, &programs_map), - bump: Some(ctx.bumps.another), - }; - - ix_handler(payer.clone(), user.clone(), another.clone()); - - dot::program::User::store(user); - - dot::program::Another::store(another.account); - - return Ok(()); - } -} -