use crate::account_view::AccountView;
use crate::address::Address;
use crate::error::ProgramError;
#[repr(transparent)]
#[derive(Clone, PartialEq, Eq)]
pub struct SignerView<'info> {
inner: AccountView<'info>,
}
impl<'info> SignerView<'info> {
#[inline(always)]
pub fn validate(view: AccountView<'info>) -> Result<Self, ProgramError> {
if view.is_signer() {
Ok(Self { inner: view })
} else {
Err(ProgramError::MissingRequiredSignature)
}
}
#[inline(always)]
pub fn as_view(&self) -> &AccountView<'info> {
&self.inner
}
#[inline(always)]
pub fn into_view(self) -> AccountView<'info> {
self.inner
}
}
impl<'info> core::ops::Deref for SignerView<'info> {
type Target = AccountView<'info>;
#[inline(always)]
fn deref(&self) -> &AccountView<'info> {
&self.inner
}
}
#[repr(transparent)]
#[derive(Clone, PartialEq, Eq)]
pub struct WritableView<'info> {
inner: AccountView<'info>,
}
impl<'info> WritableView<'info> {
#[inline(always)]
pub fn validate(view: AccountView<'info>) -> Result<Self, ProgramError> {
if view.is_writable() {
Ok(Self { inner: view })
} else {
Err(ProgramError::Immutable)
}
}
#[inline(always)]
pub fn as_view(&self) -> &AccountView<'info> {
&self.inner
}
#[inline(always)]
pub fn into_view(self) -> AccountView<'info> {
self.inner
}
}
impl<'info> core::ops::Deref for WritableView<'info> {
type Target = AccountView<'info>;
#[inline(always)]
fn deref(&self) -> &AccountView<'info> {
&self.inner
}
}
#[repr(transparent)]
#[derive(Clone, PartialEq, Eq)]
pub struct MutableView<'info> {
inner: AccountView<'info>,
}
impl<'info> MutableView<'info> {
#[inline(always)]
pub fn validate(view: AccountView<'info>) -> Result<Self, ProgramError> {
if !view.is_signer() {
return Err(ProgramError::MissingRequiredSignature);
}
if !view.is_writable() {
return Err(ProgramError::Immutable);
}
Ok(Self { inner: view })
}
#[inline(always)]
pub fn as_view(&self) -> &AccountView<'info> {
&self.inner
}
#[inline(always)]
pub fn into_view(self) -> AccountView<'info> {
self.inner
}
#[inline(always)]
pub fn as_signer(&self) -> SignerView<'info> {
SignerView {
inner: self.inner.clone(),
}
}
#[inline(always)]
pub fn as_writable(&self) -> WritableView<'info> {
WritableView {
inner: self.inner.clone(),
}
}
}
impl<'info> core::ops::Deref for MutableView<'info> {
type Target = AccountView<'info>;
#[inline(always)]
fn deref(&self) -> &AccountView<'info> {
&self.inner
}
}
#[repr(transparent)]
#[derive(Clone, PartialEq, Eq)]
pub struct OwnedView<'info> {
inner: AccountView<'info>,
}
impl<'info> OwnedView<'info> {
#[inline(always)]
pub fn validate(
view: AccountView<'info>,
expected_owner: &Address,
) -> Result<Self, ProgramError> {
if view.owned_by(expected_owner) {
Ok(Self { inner: view })
} else {
Err(ProgramError::IncorrectProgramId)
}
}
#[inline(always)]
pub fn as_view(&self) -> &AccountView<'info> {
&self.inner
}
#[inline(always)]
pub fn into_view(self) -> AccountView<'info> {
self.inner
}
}
impl<'info> core::ops::Deref for OwnedView<'info> {
type Target = AccountView<'info>;
#[inline(always)]
fn deref(&self) -> &AccountView<'info> {
&self.inner
}
}
#[repr(transparent)]
#[derive(Clone, PartialEq, Eq)]
pub struct ReadonlyView<'info> {
inner: AccountView<'info>,
}
impl<'info> ReadonlyView<'info> {
#[inline(always)]
pub fn validate(view: AccountView<'info>) -> Result<Self, ProgramError> {
if view.is_writable() {
return Err(ProgramError::InvalidArgument);
}
Ok(Self { inner: view })
}
#[inline(always)]
pub fn as_view(&self) -> &AccountView<'info> {
&self.inner
}
#[inline(always)]
pub fn into_view(self) -> AccountView<'info> {
self.inner
}
}
impl<'info> core::ops::Deref for ReadonlyView<'info> {
type Target = AccountView<'info>;
#[inline(always)]
fn deref(&self) -> &AccountView<'info> {
&self.inner
}
}
#[repr(transparent)]
#[derive(Clone, PartialEq, Eq)]
pub struct ExecutableView<'info> {
inner: AccountView<'info>,
}
impl<'info> ExecutableView<'info> {
#[inline(always)]
pub fn validate(view: AccountView<'info>) -> Result<Self, ProgramError> {
if view.executable() {
Ok(Self { inner: view })
} else {
Err(ProgramError::InvalidArgument)
}
}
#[inline(always)]
pub fn as_view(&self) -> &AccountView<'info> {
&self.inner
}
#[inline(always)]
pub fn into_view(self) -> AccountView<'info> {
self.inner
}
}
impl<'info> core::ops::Deref for ExecutableView<'info> {
type Target = AccountView<'info>;
#[inline(always)]
fn deref(&self) -> &AccountView<'info> {
&self.inner
}
}
impl<'info> crate::lazy::LazyContext<'info> {
#[inline]
pub fn next_validated_signer(&mut self) -> Result<SignerView<'info>, ProgramError> {
let acct = self.next_account()?;
SignerView::validate(acct)
}
#[inline]
pub fn next_validated_writable(&mut self) -> Result<WritableView<'info>, ProgramError> {
let acct = self.next_account()?;
WritableView::validate(acct)
}
#[inline]
pub fn next_validated_mutable(&mut self) -> Result<MutableView<'info>, ProgramError> {
let acct = self.next_account()?;
MutableView::validate(acct)
}
#[inline]
pub fn next_validated_owned(
&mut self,
owner: &Address,
) -> Result<OwnedView<'info>, ProgramError> {
let acct = self.next_account()?;
OwnedView::validate(acct, owner)
}
#[inline]
pub fn next_validated_executable(&mut self) -> Result<ExecutableView<'info>, ProgramError> {
let acct = self.next_account()?;
ExecutableView::validate(acct)
}
}