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