use crate::{instruction::Instruction, prelude::*};
use star_frame_idl::{
account::IdlAccountId, account_set::IdlAccountSetDef, instruction::IdlInstructionDef,
seeds::IdlSeeds, ty::IdlTypeDef, CrateMetadata, IdlDefinition, IdlMetadata,
};
mod find_seeds;
mod ty;
pub use find_seeds::*;
pub(crate) use ty::*;
pub trait InstructionSetToIdl: InstructionSet {
fn instruction_set_to_idl(idl_definition: &mut IdlDefinition) -> crate::IdlResult<()>;
}
pub trait InstructionToIdl<A>: Instruction {
fn instruction_to_idl(
idl_definition: &mut IdlDefinition,
arg: A,
) -> crate::IdlResult<IdlInstructionDef>;
}
pub trait AccountSetToIdl<A> {
fn account_set_to_idl(
idl_definition: &mut IdlDefinition,
arg: A,
) -> crate::IdlResult<IdlAccountSetDef>;
}
pub trait AccountToIdl: TypeToIdl {
fn account_to_idl(idl_definition: &mut IdlDefinition) -> crate::IdlResult<IdlAccountId>;
}
pub trait TypeToIdl {
type AssociatedProgram: ProgramToIdl;
fn type_to_idl(idl_definition: &mut IdlDefinition) -> crate::IdlResult<IdlTypeDef>;
}
pub trait SeedsToIdl: GetSeeds {
fn seeds_to_idl(idl_definition: &mut IdlDefinition) -> crate::IdlResult<IdlSeeds>;
}
pub trait ErrorsToIdl {
fn errors_to_idl(idl_definition: &mut IdlDefinition) -> crate::IdlResult<()>;
}
impl ErrorsToIdl for () {
fn errors_to_idl(_idl_definition: &mut IdlDefinition) -> crate::IdlResult<()> {
Ok(())
}
}
#[doc(hidden)]
#[must_use]
pub fn empty_env_option(env: &str) -> Option<String> {
if env.is_empty() {
None
} else {
Some(env.to_string())
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! crate_metadata {
() => {
$crate::star_frame_idl::CrateMetadata {
version: $crate::star_frame_idl::Version::parse(env!("CARGO_PKG_VERSION"))
.expect("Invalid package version. This should never happen."),
name: env!("CARGO_PKG_NAME").to_string(),
description: $crate::idl::empty_env_option(env!("CARGO_PKG_DESCRIPTION")),
docs: vec![],
homepage: $crate::idl::empty_env_option(env!("CARGO_PKG_HOMEPAGE")),
license: $crate::idl::empty_env_option(env!("CARGO_PKG_LICENSE")),
repository: $crate::idl::empty_env_option(env!("CARGO_PKG_REPOSITORY")),
}
};
}
pub trait ProgramToIdl: StarFrameProgram {
type Errors: ErrorsToIdl;
#[must_use]
fn crate_metadata() -> CrateMetadata {
CrateMetadata {
..crate_metadata!()
}
}
fn modify_idl(_idl_definition: &mut IdlDefinition) -> crate::IdlResult<()> {
Ok(())
}
fn program_to_idl() -> crate::IdlResult<IdlDefinition>
where
<Self as StarFrameProgram>::InstructionSet: InstructionSetToIdl,
{
let mut out = IdlDefinition {
address: Self::ID,
metadata: IdlMetadata {
crate_metadata: Self::crate_metadata(),
..Default::default()
},
..Default::default()
};
<Self as StarFrameProgram>::InstructionSet::instruction_set_to_idl(&mut out)?;
Self::Errors::errors_to_idl(&mut out)?;
Self::modify_idl(&mut out)?;
Ok(out)
}
}