Apply clippy rules (#431)

This commit is contained in:
Kirill Fomichev 2021-06-28 03:09:46 +03:00 committed by GitHub
parent dc6227fc86
commit 1aa019cb0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 130 additions and 143 deletions

View File

@ -12,7 +12,7 @@ git:
_defaults: &defaults _defaults: &defaults
before_install: before_install:
- rustup component add rustfmt - rustup component add rustfmt clippy
- nvm install $NODE_VERSION - nvm install $NODE_VERSION
- sudo apt-get install -y pkg-config build-essential libudev-dev - sudo apt-get install -y pkg-config build-essential libudev-dev
@ -41,6 +41,7 @@ jobs:
script: script:
- cargo build - cargo build
- cargo fmt -- --check - cargo fmt -- --check
- cargo clippy --all-targets -- -D warnings
- cargo test - cargo test
- <<: *examples - <<: *examples
name: Runs the examples 1 name: Runs the examples 1

4
Cargo.lock generated
View File

@ -1087,9 +1087,9 @@ checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da"
[[package]] [[package]]
name = "field-offset" name = "field-offset"
version = "0.3.3" version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf539fba70056b50f40a22e0da30639518a12ee18c35807858a63b158cb6dde7" checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92"
dependencies = [ dependencies = [
"memoffset 0.6.1", "memoffset 0.6.1",
"rustc_version 0.3.3", "rustc_version 0.3.3",

View File

@ -118,7 +118,7 @@ impl ToString for Config {
fn to_string(&self) -> String { fn to_string(&self) -> String {
let clusters = { let clusters = {
let c = ser_clusters(&self.clusters); let c = ser_clusters(&self.clusters);
if c.len() == 0 { if c.is_empty() {
None None
} else { } else {
Some(c) Some(c)
@ -152,11 +152,9 @@ impl FromStr for Config {
cluster: cfg.provider.cluster.parse()?, cluster: cfg.provider.cluster.parse()?,
wallet: shellexpand::tilde(&cfg.provider.wallet).parse()?, wallet: shellexpand::tilde(&cfg.provider.wallet).parse()?,
}, },
scripts: cfg.scripts.unwrap_or_else(|| BTreeMap::new()), scripts: cfg.scripts.unwrap_or_else(BTreeMap::new),
test: cfg.test, test: cfg.test,
clusters: cfg clusters: cfg.clusters.map_or(Ok(BTreeMap::new()), deser_clusters)?,
.clusters
.map_or(Ok(BTreeMap::new()), |c| deser_clusters(c))?,
}) })
} }
} }

View File

@ -311,7 +311,7 @@ fn init(cfg_override: &ConfigOverride, name: String, typescript: bool) -> Result
ts_config.write_all(template::ts_config().as_bytes())?; ts_config.write_all(template::ts_config().as_bytes())?;
let mut deploy = File::create("migrations/deploy.ts")?; let mut deploy = File::create("migrations/deploy.ts")?;
deploy.write_all(&template::ts_deploy_script().as_bytes())?; deploy.write_all(template::ts_deploy_script().as_bytes())?;
let mut mocha = File::create(&format!("tests/{}.spec.ts", name))?; let mut mocha = File::create(&format!("tests/{}.spec.ts", name))?;
mocha.write_all(template::ts_mocha(&name).as_bytes())?; mocha.write_all(template::ts_mocha(&name).as_bytes())?;
@ -320,7 +320,7 @@ fn init(cfg_override: &ConfigOverride, name: String, typescript: bool) -> Result
mocha.write_all(template::mocha(&name).as_bytes())?; mocha.write_all(template::mocha(&name).as_bytes())?;
let mut deploy = File::create("migrations/deploy.js")?; let mut deploy = File::create("migrations/deploy.js")?;
deploy.write_all(&template::deploy_script().as_bytes())?; deploy.write_all(template::deploy_script().as_bytes())?;
} }
println!("{} initialized", name); println!("{} initialized", name);
@ -350,11 +350,11 @@ fn new_program(name: &str) -> Result<()> {
fs::create_dir(&format!("programs/{}", name))?; fs::create_dir(&format!("programs/{}", name))?;
fs::create_dir(&format!("programs/{}/src/", name))?; fs::create_dir(&format!("programs/{}/src/", name))?;
let mut cargo_toml = File::create(&format!("programs/{}/Cargo.toml", name))?; let mut cargo_toml = File::create(&format!("programs/{}/Cargo.toml", name))?;
cargo_toml.write_all(template::cargo_toml(&name).as_bytes())?; cargo_toml.write_all(template::cargo_toml(name).as_bytes())?;
let mut xargo_toml = File::create(&format!("programs/{}/Xargo.toml", name))?; let mut xargo_toml = File::create(&format!("programs/{}/Xargo.toml", name))?;
xargo_toml.write_all(template::xargo_toml().as_bytes())?; xargo_toml.write_all(template::xargo_toml().as_bytes())?;
let mut lib_rs = File::create(&format!("programs/{}/src/lib.rs", name))?; let mut lib_rs = File::create(&format!("programs/{}/src/lib.rs", name))?;
lib_rs.write_all(template::lib_rs(&name).as_bytes())?; lib_rs.write_all(template::lib_rs(name).as_bytes())?;
Ok(()) Ok(())
} }
@ -458,7 +458,7 @@ fn build_cwd_verifiable(workspace_dir: &Path) -> Result<()> {
.args(&[ .args(&[
"run", "run",
"--name", "--name",
&container_name, container_name,
"-v", "-v",
&volume_mount, &volume_mount,
&image_name, &image_name,
@ -504,7 +504,7 @@ fn build_cwd_verifiable(workspace_dir: &Path) -> Result<()> {
// Remove the docker image. // Remove the docker image.
let exit = std::process::Command::new("docker") let exit = std::process::Command::new("docker")
.args(&["rm", &container_name]) .args(&["rm", container_name])
.stdout(Stdio::inherit()) .stdout(Stdio::inherit())
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.output() .output()
@ -540,7 +540,7 @@ fn _build_cwd(idl_out: Option<PathBuf>) -> Result<()> {
fn verify(cfg_override: &ConfigOverride, program_id: Pubkey) -> Result<()> { fn verify(cfg_override: &ConfigOverride, program_id: Pubkey) -> Result<()> {
let (cfg, _path, cargo) = Config::discover(cfg_override)?.expect("Not in workspace."); let (cfg, _path, cargo) = Config::discover(cfg_override)?.expect("Not in workspace.");
let cargo = cargo.ok_or(anyhow!("Must be inside program subdirectory."))?; let cargo = cargo.ok_or_else(|| anyhow!("Must be inside program subdirectory."))?;
let program_dir = cargo.parent().unwrap(); let program_dir = cargo.parent().unwrap();
// Build the program we want to verify. // Build the program we want to verify.
@ -692,7 +692,7 @@ fn idl_init(cfg_override: &ConfigOverride, program_id: Pubkey, idl_filepath: Str
let bytes = std::fs::read(idl_filepath)?; let bytes = std::fs::read(idl_filepath)?;
let idl: Idl = serde_json::from_reader(&*bytes)?; let idl: Idl = serde_json::from_reader(&*bytes)?;
let idl_address = create_idl_account(&cfg, &keypair, &program_id, &idl)?; let idl_address = create_idl_account(cfg, &keypair, &program_id, &idl)?;
println!("Idl account created: {:?}", idl_address); println!("Idl account created: {:?}", idl_address);
Ok(()) Ok(())
@ -710,8 +710,8 @@ fn idl_write_buffer(
let bytes = std::fs::read(idl_filepath)?; let bytes = std::fs::read(idl_filepath)?;
let idl: Idl = serde_json::from_reader(&*bytes)?; let idl: Idl = serde_json::from_reader(&*bytes)?;
let idl_buffer = create_idl_buffer(&cfg, &keypair, &program_id, &idl)?; let idl_buffer = create_idl_buffer(cfg, &keypair, &program_id, &idl)?;
idl_write(&cfg, &program_id, &idl, idl_buffer)?; idl_write(cfg, &program_id, &idl, idl_buffer)?;
println!("Idl buffer created: {:?}", idl_buffer); println!("Idl buffer created: {:?}", idl_buffer);
@ -988,10 +988,8 @@ fn test(
// //
// In either case, skip the deploy if the user specifies. // In either case, skip the deploy if the user specifies.
let is_localnet = cfg.provider.cluster == Cluster::Localnet; let is_localnet = cfg.provider.cluster == Cluster::Localnet;
if !is_localnet || (is_localnet && skip_local_validator) { if (!is_localnet || skip_local_validator) && !skip_deploy {
if !skip_deploy { deploy(cfg_override, None)?;
deploy(cfg_override, None)?;
}
} }
// Start local test validator, if needed. // Start local test validator, if needed.
let mut validator_handle = None; let mut validator_handle = None;
@ -1004,7 +1002,7 @@ fn test(
} }
// Setup log reader. // Setup log reader.
let log_streams = stream_logs(&cfg.provider.cluster.url()); let log_streams = stream_logs(cfg.provider.cluster.url());
// Run the tests. // Run the tests.
let test_result: Result<_> = { let test_result: Result<_> = {
@ -1298,7 +1296,7 @@ fn launch(
) -> Result<()> { ) -> Result<()> {
// Build and deploy. // Build and deploy.
build(cfg_override, None, verifiable, program_name.clone())?; build(cfg_override, None, verifiable, program_name.clone())?;
let programs = _deploy(cfg_override, program_name.clone())?; let programs = _deploy(cfg_override, program_name)?;
with_workspace(cfg_override, |cfg, _path, _cargo| { with_workspace(cfg_override, |cfg, _path, _cargo| {
let keypair = cfg.provider.wallet.to_string(); let keypair = cfg.provider.wallet.to_string();
@ -1306,7 +1304,7 @@ fn launch(
// Add metadata to all IDLs. // Add metadata to all IDLs.
for (address, program) in programs { for (address, program) in programs {
// Store the IDL on chain. // Store the IDL on chain.
let idl_address = create_idl_account(&cfg, &keypair, &address, &program.idl)?; let idl_address = create_idl_account(cfg, &keypair, &address, &program.idl)?;
println!("IDL account created: {}", idl_address.to_string()); println!("IDL account created: {}", idl_address.to_string());
} }
@ -1589,7 +1587,7 @@ fn shell(cfg_override: &ConfigOverride) -> Result<()> {
.map(|program| (program.idl.name.clone(), program.idl.clone())) .map(|program| (program.idl.name.clone(), program.idl.clone()))
.collect(); .collect();
// Insert all manually specified idls into the idl map. // Insert all manually specified idls into the idl map.
cfg.clusters.get(&cfg.provider.cluster).map(|programs| { if let Some(programs) = cfg.clusters.get(&cfg.provider.cluster) {
let _ = programs let _ = programs
.iter() .iter()
.map(|(name, pd)| { .map(|(name, pd)| {
@ -1601,7 +1599,7 @@ fn shell(cfg_override: &ConfigOverride) -> Result<()> {
} }
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
}); }
match cfg.clusters.get(&cfg.provider.cluster) { match cfg.clusters.get(&cfg.provider.cluster) {
None => Vec::new(), None => Vec::new(),
Some(programs) => programs Some(programs) => programs
@ -1645,7 +1643,7 @@ fn run(cfg_override: &ConfigOverride, script: String) -> Result<()> {
let script = cfg let script = cfg
.scripts .scripts
.get(&script) .get(&script)
.ok_or(anyhow!("Unable to find script"))?; .ok_or_else(|| anyhow!("Unable to find script"))?;
let exit = std::process::Command::new("bash") let exit = std::process::Command::new("bash")
.arg("-c") .arg("-c")
.arg(&script) .arg(&script)

View File

@ -91,7 +91,7 @@ impl Program {
pub fn request(&self) -> RequestBuilder { pub fn request(&self) -> RequestBuilder {
RequestBuilder::from( RequestBuilder::from(
self.program_id, self.program_id,
&self.cfg.cluster.url(), self.cfg.cluster.url(),
Keypair::from_bytes(&self.cfg.payer.to_bytes()).unwrap(), Keypair::from_bytes(&self.cfg.payer.to_bytes()).unwrap(),
self.cfg.options, self.cfg.options,
RequestNamespace::Global, RequestNamespace::Global,
@ -102,7 +102,7 @@ impl Program {
pub fn state_request(&self) -> RequestBuilder { pub fn state_request(&self) -> RequestBuilder {
RequestBuilder::from( RequestBuilder::from(
self.program_id, self.program_id,
&self.cfg.cluster.url(), self.cfg.cluster.url(),
Keypair::from_bytes(&self.cfg.payer.to_bytes()).unwrap(), Keypair::from_bytes(&self.cfg.payer.to_bytes()).unwrap(),
self.cfg.options, self.cfg.options,
RequestNamespace::State { new: false }, RequestNamespace::State { new: false },
@ -140,7 +140,7 @@ impl Program {
pub fn on<T: anchor_lang::Event + anchor_lang::AnchorDeserialize>( pub fn on<T: anchor_lang::Event + anchor_lang::AnchorDeserialize>(
&self, &self,
f: impl Fn(&EventContext, T) -> () + Send + 'static, f: impl Fn(&EventContext, T) + Send + 'static,
) -> Result<EventHandle, ClientError> { ) -> Result<EventHandle, ClientError> {
let addresses = vec![self.program_id.to_string()]; let addresses = vec![self.program_id.to_string()];
let filter = RpcTransactionLogsFilter::Mentions(addresses); let filter = RpcTransactionLogsFilter::Mentions(addresses);
@ -149,7 +149,7 @@ impl Program {
commitment: self.cfg.options, commitment: self.cfg.options,
}; };
let self_program_str = self.program_id.to_string(); let self_program_str = self.program_id.to_string();
let (client, receiver) = PubsubClient::logs_subscribe(&ws_url, filter.clone(), cfg)?; let (client, receiver) = PubsubClient::logs_subscribe(&ws_url, filter, cfg)?;
std::thread::spawn(move || { std::thread::spawn(move || {
loop { loop {
match receiver.recv() { match receiver.recv() {
@ -159,23 +159,24 @@ impl Program {
slot: logs.context.slot, slot: logs.context.slot,
}; };
let mut logs = &logs.value.logs[..]; let mut logs = &logs.value.logs[..];
if logs.len() > 0 { if !logs.is_empty() {
if let Ok(mut execution) = Execution::new(&mut logs) { if let Ok(mut execution) = Execution::new(&mut logs) {
for l in logs { for l in logs {
// Parse the log. // Parse the log.
let (event, new_program, did_pop) = { let (event, new_program, did_pop) = {
if self_program_str == execution.program() { if self_program_str == execution.program() {
handle_program_log(&self_program_str, &l) handle_program_log(&self_program_str, l).unwrap_or_else(
.unwrap_or_else(|e| { |e| {
println!( println!(
"Unable to parse log: {}", "Unable to parse log: {}",
e.to_string() e.to_string()
); );
std::process::exit(1); std::process::exit(1);
}) },
)
} else { } else {
let (program, did_pop) = let (program, did_pop) =
handle_system_log(&self_program_str, &l); handle_system_log(&self_program_str, l);
(None, program, did_pop) (None, program, did_pop)
} }
}; };
@ -232,7 +233,7 @@ fn handle_program_log<T: anchor_lang::Event + anchor_lang::AnchorDeserialize>(
} }
// System log. // System log.
else { else {
let (program, did_pop) = handle_system_log(&self_program_str, &l); let (program, did_pop) = handle_system_log(self_program_str, l);
Ok((None, program, did_pop)) Ok((None, program, did_pop))
} }
} }
@ -264,10 +265,10 @@ impl Execution {
let re = Regex::new(r"^Program (.*) invoke.*$").unwrap(); let re = Regex::new(r"^Program (.*) invoke.*$").unwrap();
let c = re let c = re
.captures(l) .captures(l)
.ok_or(ClientError::LogParseError(l.to_string()))?; .ok_or_else(|| ClientError::LogParseError(l.to_string()))?;
let program = c let program = c
.get(1) .get(1)
.ok_or(ClientError::LogParseError(l.to_string()))? .ok_or_else(|| ClientError::LogParseError(l.to_string()))?
.as_str() .as_str()
.to_string(); .to_string();
Ok(Self { Ok(Self {
@ -276,7 +277,7 @@ impl Execution {
} }
pub fn program(&self) -> String { pub fn program(&self) -> String {
assert!(self.stack.len() > 0); assert!(!self.stack.is_empty());
self.stack[self.stack.len() - 1].clone() self.stack[self.stack.len() - 1].clone()
} }
@ -285,7 +286,7 @@ impl Execution {
} }
pub fn pop(&mut self) { pub fn pop(&mut self) {
assert!(self.stack.len() > 0); assert!(!self.stack.is_empty());
self.stack.pop().unwrap(); self.stack.pop().unwrap();
} }
} }
@ -394,6 +395,7 @@ impl<'a> RequestBuilder<'a> {
} }
/// Invokes the `#[state]`'s `new` constructor. /// Invokes the `#[state]`'s `new` constructor.
#[allow(clippy::wrong_self_convention)]
pub fn new(mut self, args: impl InstructionData) -> Self { pub fn new(mut self, args: impl InstructionData) -> Self {
assert!(self.namespace == RequestNamespace::State { new: false }); assert!(self.namespace == RequestNamespace::State { new: false });
self.namespace = RequestNamespace::State { new: true }; self.namespace = RequestNamespace::State { new: true };
@ -483,7 +485,7 @@ mod tests {
let log = "Program 7Y8VDzehoewALqJfyxZYMgYCnMTCDhWuGfJKUvjYWATw success"; let log = "Program 7Y8VDzehoewALqJfyxZYMgYCnMTCDhWuGfJKUvjYWATw success";
let (program, did_pop) = handle_system_log("asdf", log); let (program, did_pop) = handle_system_log("asdf", log);
assert_eq!(program, None); assert_eq!(program, None);
assert_eq!(did_pop, true); assert!(did_pop);
} }
#[test] #[test]
@ -491,6 +493,6 @@ mod tests {
let log = "Program 7swsTUiQ6KUK4uFYquQKg4epFRsBnvbrTf2fZQCa2sTJ qwer"; let log = "Program 7swsTUiQ6KUK4uFYquQKg4epFRsBnvbrTf2fZQCa2sTJ qwer";
let (program, did_pop) = handle_system_log("asdf", log); let (program, did_pop) = handle_system_log("asdf", log);
assert_eq!(program, None); assert_eq!(program, None);
assert_eq!(did_pop, false); assert!(!did_pop);
} }
} }

View File

@ -59,10 +59,10 @@ pub fn account(
) -> proc_macro::TokenStream { ) -> proc_macro::TokenStream {
let mut namespace = "".to_string(); let mut namespace = "".to_string();
let mut is_zero_copy = false; let mut is_zero_copy = false;
if args.to_string().split(",").collect::<Vec<_>>().len() > 2 { if args.to_string().split(',').count() > 2 {
panic!("Only two args are allowed to the account attribute.") panic!("Only two args are allowed to the account attribute.")
} }
for arg in args.to_string().split(",") { for arg in args.to_string().split(',') {
let ns = arg let ns = arg
.to_string() .to_string()
.replace("\"", "") .replace("\"", "")
@ -264,14 +264,7 @@ pub fn derive_zero_copy_accessor(item: proc_macro::TokenStream) -> proc_macro::T
field field
.attrs .attrs
.iter() .iter()
.filter(|attr| { .find(|attr| anchor_syn::parser::tts_to_string(&attr.path) == "accessor")
let name = anchor_syn::parser::tts_to_string(&attr.path);
if name != "accessor" {
return false;
}
return true;
})
.next()
.map(|attr| { .map(|attr| {
let mut tts = attr.tokens.clone().into_iter(); let mut tts = attr.tokens.clone().into_iter();
let g_stream = match tts.next().expect("Must have a token group") { let g_stream = match tts.next().expect("Must have a token group") {

View File

@ -46,24 +46,22 @@ pub fn state(
} }
} }
} }
} else { } else if is_zero_copy {
if is_zero_copy { quote! {
quote! { impl anchor_lang::__private::AccountSize for #struct_ident {
impl anchor_lang::__private::AccountSize for #struct_ident { fn size(&self) -> std::result::Result<u64, anchor_lang::solana_program::program_error::ProgramError> {
fn size(&self) -> std::result::Result<u64, anchor_lang::solana_program::program_error::ProgramError> { let len = anchor_lang::__private::bytemuck::bytes_of(self).len() as u64;
let len = anchor_lang::__private::bytemuck::bytes_of(self).len() as u64; Ok(8 + len)
Ok(8 + len)
}
} }
} }
} else { }
let size = proc_macro2::TokenStream::from(args.clone()); } else {
// Size override given to the macro. Use it. let size = proc_macro2::TokenStream::from(args);
quote! { // Size override given to the macro. Use it.
impl anchor_lang::__private::AccountSize for #struct_ident { quote! {
fn size(&self) -> std::result::Result<u64, anchor_lang::solana_program::program_error::ProgramError> { impl anchor_lang::__private::AccountSize for #struct_ident {
Ok(#size) fn size(&self) -> std::result::Result<u64, anchor_lang::solana_program::program_error::ProgramError> {
} Ok(#size)
} }
} }
} }

View File

@ -21,8 +21,8 @@ impl<'a, 'b, 'c, 'info, T: Accounts<'info>> Context<'a, 'b, 'c, 'info, T> {
remaining_accounts: &'c [AccountInfo<'info>], remaining_accounts: &'c [AccountInfo<'info>],
) -> Self { ) -> Self {
Self { Self {
accounts,
program_id, program_id,
accounts,
remaining_accounts, remaining_accounts,
} }
} }

View File

@ -10,7 +10,7 @@ use solana_program::program_error::ProgramError;
use solana_program::pubkey::Pubkey; use solana_program::pubkey::Pubkey;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
pub const PROGRAM_STATE_SEED: &'static str = "unversioned"; pub const PROGRAM_STATE_SEED: &str = "unversioned";
/// Boxed container for the program state singleton. /// Boxed container for the program state singleton.
#[derive(Clone)] #[derive(Clone)]

View File

@ -19,7 +19,7 @@ impl<'info, T: solana_program::sysvar::Sysvar> Sysvar<'info, T> {
) -> Result<Sysvar<'info, T>, ProgramError> { ) -> Result<Sysvar<'info, T>, ProgramError> {
Ok(Sysvar { Ok(Sysvar {
info: acc_info.clone(), info: acc_info.clone(),
account: T::from_account_info(&acc_info)?, account: T::from_account_info(acc_info)?,
}) })
} }
} }

View File

@ -73,19 +73,9 @@ pub fn linearize(c_group: &ConstraintGroup) -> Vec<Constraint> {
if let Some(c) = signer { if let Some(c) = signer {
constraints.push(Constraint::Signer(c)); constraints.push(Constraint::Signer(c));
} }
constraints.append( constraints.append(&mut belongs_to.into_iter().map(Constraint::BelongsTo).collect());
&mut belongs_to constraints.append(&mut literal.into_iter().map(Constraint::Literal).collect());
.into_iter() constraints.append(&mut raw.into_iter().map(Constraint::Raw).collect());
.map(|c| Constraint::BelongsTo(c))
.collect(),
);
constraints.append(
&mut literal
.into_iter()
.map(|c| Constraint::Literal(c))
.collect(),
);
constraints.append(&mut raw.into_iter().map(|c| Constraint::Raw(c)).collect());
if let Some(c) = owner { if let Some(c) = owner {
constraints.push(Constraint::Owner(c)); constraints.push(Constraint::Owner(c));
} }
@ -405,7 +395,7 @@ pub fn generate_pda(
kind: &PdaKind, kind: &PdaKind,
) -> proc_macro2::TokenStream { ) -> proc_macro2::TokenStream {
let field = &f.ident; let field = &f.ident;
let (account_ty, account_wrapper_ty, is_zero_copy) = parse_ty(&f); let (account_ty, account_wrapper_ty, is_zero_copy) = parse_ty(f);
let space = match space { let space = match space {
// If no explicit space param was given, serialize the type to bytes // If no explicit space param was given, serialize the type to bytes
@ -647,7 +637,7 @@ pub fn generate_constraint_state(f: &Field, c: &ConstraintState) -> proc_macro2:
// Returns the inner part of the seeds slice as a token stream. // Returns the inner part of the seeds slice as a token stream.
fn to_seeds_tts(seeds: &[syn::Expr]) -> proc_macro2::TokenStream { fn to_seeds_tts(seeds: &[syn::Expr]) -> proc_macro2::TokenStream {
assert!(seeds.len() > 0); assert!(!seeds.is_empty());
let seed_0 = &seeds[0]; let seed_0 = &seeds[0];
let mut tts = match seed_0 { let mut tts = match seed_0 {
syn::Expr::Path(_) => quote! { syn::Expr::Path(_) => quote! {

View File

@ -35,7 +35,7 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
*accounts = &accounts[1..]; *accounts = &accounts[1..];
} }
} else { } else {
let name = typed_ident(&f); let name = typed_ident(f);
match f.constraints.is_init() { match f.constraints.is_init() {
false => quote! { false => quote! {
#[cfg(feature = "anchor-debug")] #[cfg(feature = "anchor-debug")]

View File

@ -52,9 +52,9 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
}) })
.collect() .collect()
}) })
.unwrap_or(vec![]) .unwrap_or_else(Vec::new)
}) })
.unwrap_or(vec![]); .unwrap_or_else(Vec::new);
// Generate cpi methods for global methods. // Generate cpi methods for global methods.
let global_cpi_methods: Vec<proc_macro2::TokenStream> = program let global_cpi_methods: Vec<proc_macro2::TokenStream> = program
.ixs .ixs
@ -66,7 +66,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
let method_name = &ix.ident; let method_name = &ix.ident;
let args: Vec<&syn::PatType> = ix.args.iter().map(|arg| &arg.raw_arg).collect(); let args: Vec<&syn::PatType> = ix.args.iter().map(|arg| &arg.raw_arg).collect();
let name = &ix.raw_method.sig.ident.to_string(); let name = &ix.raw_method.sig.ident.to_string();
let sighash_arr = sighash(SIGHASH_GLOBAL_NAMESPACE, &name); let sighash_arr = sighash(SIGHASH_GLOBAL_NAMESPACE, name);
let sighash_tts: proc_macro2::TokenStream = let sighash_tts: proc_macro2::TokenStream =
format!("{:?}", sighash_arr).parse().unwrap(); format!("{:?}", sighash_arr).parse().unwrap();
quote! { quote! {

View File

@ -38,7 +38,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
let name = &ix.raw_method.sig.ident.to_string(); let name = &ix.raw_method.sig.ident.to_string();
let ix_method_name: proc_macro2::TokenStream = let ix_method_name: proc_macro2::TokenStream =
{ format!("__{}", name).parse().unwrap() }; { format!("__{}", name).parse().unwrap() };
let sighash_arr = sighash(SIGHASH_STATE_NAMESPACE, &name); let sighash_arr = sighash(SIGHASH_STATE_NAMESPACE, name);
let sighash_tts: proc_macro2::TokenStream = let sighash_tts: proc_macro2::TokenStream =
format!("{:?}", sighash_arr).parse().unwrap(); format!("{:?}", sighash_arr).parse().unwrap();
quote! { quote! {

View File

@ -134,7 +134,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
}) })
.collect(); .collect();
let ix_data_trait = { let ix_data_trait = {
let sighash_arr = sighash(SIGHASH_GLOBAL_NAMESPACE, &name); let sighash_arr = sighash(SIGHASH_GLOBAL_NAMESPACE, name);
let sighash_tts: proc_macro2::TokenStream = let sighash_tts: proc_macro2::TokenStream =
format!("{:?}", sighash_arr).parse().unwrap(); format!("{:?}", sighash_arr).parse().unwrap();
quote! { quote! {

View File

@ -7,7 +7,6 @@ use quote::ToTokens;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::iter::FromIterator;
use std::path::Path; use std::path::Path;
const DERIVE_NAME: &str = "Accounts"; const DERIVE_NAME: &str = "Accounts";
@ -57,8 +56,8 @@ pub fn parse(filename: impl AsRef<Path>) -> Result<Idl> {
let accounts = idl_accounts(accounts_strct, &accs); let accounts = idl_accounts(accounts_strct, &accs);
IdlInstruction { IdlInstruction {
name, name,
args,
accounts, accounts,
args,
} }
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
@ -93,11 +92,11 @@ pub fn parse(filename: impl AsRef<Path>) -> Result<Idl> {
}) })
.collect(); .collect();
let accounts_strct = accs.get(&anchor_ident.to_string()).unwrap(); let accounts_strct = accs.get(&anchor_ident.to_string()).unwrap();
let accounts = idl_accounts(&accounts_strct, &accs); let accounts = idl_accounts(accounts_strct, &accs);
IdlInstruction { IdlInstruction {
name, name,
args,
accounts, accounts,
args,
} }
}; };
@ -181,13 +180,13 @@ pub fn parse(filename: impl AsRef<Path>) -> Result<Idl> {
.named .named
.iter() .iter()
.map(|f: &syn::Field| { .map(|f: &syn::Field| {
let index = match f.attrs.iter().next() { let index = match f.attrs.get(0) {
None => false, None => false,
Some(i) => parser::tts_to_string(&i.path) == "index", Some(i) => parser::tts_to_string(&i.path) == "index",
}; };
IdlEventField { IdlEventField {
name: f.ident.clone().unwrap().to_string().to_mixed_case(), name: f.ident.clone().unwrap().to_string().to_mixed_case(),
ty: parser::tts_to_string(&f.ty).to_string().parse().unwrap(), ty: parser::tts_to_string(&f.ty).parse().unwrap(),
index, index,
} }
}) })
@ -206,8 +205,10 @@ pub fn parse(filename: impl AsRef<Path>) -> Result<Idl> {
let ty_defs = parse_ty_defs(&f)?; let ty_defs = parse_ty_defs(&f)?;
let account_structs = parse_accounts(&f); let account_structs = parse_accounts(&f);
let account_names: HashSet<String> = let account_names: HashSet<String> = account_structs
HashSet::from_iter(account_structs.iter().map(|a| a.ident.to_string())); .iter()
.map(|a| a.ident.to_string())
.collect::<HashSet<_>>();
let error_name = error.map(|e| e.name).unwrap_or_else(|| "".to_string()); let error_name = error.map(|e| e.name).unwrap_or_else(|| "".to_string());
@ -217,7 +218,7 @@ pub fn parse(filename: impl AsRef<Path>) -> Result<Idl> {
if ty_def.name != error_name { if ty_def.name != error_name {
if account_names.contains(&ty_def.name) { if account_names.contains(&ty_def.name) {
accounts.push(ty_def); accounts.push(ty_def);
} else if events.iter().position(|e| e.name == ty_def.name).is_none() { } else if !events.iter().any(|e| e.name == ty_def.name) {
types.push(ty_def); types.push(ty_def);
} }
} }

View File

@ -153,11 +153,11 @@ impl std::str::FromStr for IdlType {
"Pubkey" => IdlType::PublicKey, "Pubkey" => IdlType::PublicKey,
_ => match s.to_string().strip_prefix("Option<") { _ => match s.to_string().strip_prefix("Option<") {
None => match s.to_string().strip_prefix("Vec<") { None => match s.to_string().strip_prefix("Vec<") {
None => match s.to_string().strip_prefix("[") { None => match s.to_string().strip_prefix('[') {
None => IdlType::Defined(s.to_string()), None => IdlType::Defined(s.to_string()),
Some(inner) => { Some(inner) => {
let inner = &inner[..inner.len() - 1]; let inner = &inner[..inner.len() - 1];
let mut parts = inner.split(";"); let mut parts = inner.split(';');
let ty = IdlType::from_str(parts.next().unwrap()).unwrap(); let ty = IdlType::from_str(parts.next().unwrap()).unwrap();
let len = parts.next().unwrap().parse::<usize>().unwrap(); let len = parts.next().unwrap().parse::<usize>().unwrap();
assert!(parts.next().is_none()); assert!(parts.next().is_none());
@ -167,7 +167,7 @@ impl std::str::FromStr for IdlType {
Some(inner) => { Some(inner) => {
let inner_ty = Self::from_str( let inner_ty = Self::from_str(
inner inner
.strip_suffix(">") .strip_suffix('>')
.ok_or_else(|| anyhow::anyhow!("Invalid option"))?, .ok_or_else(|| anyhow::anyhow!("Invalid option"))?,
)?; )?;
IdlType::Vec(Box::new(inner_ty)) IdlType::Vec(Box::new(inner_ty))
@ -176,7 +176,7 @@ impl std::str::FromStr for IdlType {
Some(inner) => { Some(inner) => {
let inner_ty = Self::from_str( let inner_ty = Self::from_str(
inner inner
.strip_suffix(">") .strip_suffix('>')
.ok_or_else(|| anyhow::anyhow!("Invalid option"))?, .ok_or_else(|| anyhow::anyhow!("Invalid option"))?,
)?; )?;
IdlType::Option(Box::new(inner_ty)) IdlType::Option(Box::new(inner_ty))

View File

@ -140,6 +140,7 @@ impl AccountsStruct {
} }
} }
#[allow(clippy::large_enum_variant)]
#[derive(Debug)] #[derive(Debug)]
pub enum AccountField { pub enum AccountField {
Field(Field), Field(Field),
@ -292,6 +293,7 @@ impl ConstraintGroup {
// A single account constraint *after* merging all tokens into a well formed // A single account constraint *after* merging all tokens into a well formed
// constraint. Some constraints like "associated" are defined by multiple // constraint. Some constraints like "associated" are defined by multiple
// tokens, so a merging phase is required. // tokens, so a merging phase is required.
#[allow(clippy::large_enum_variant)]
#[derive(Debug)] #[derive(Debug)]
pub enum Constraint { pub enum Constraint {
Init(ConstraintInit), Init(ConstraintInit),
@ -311,6 +313,7 @@ pub enum Constraint {
} }
// Constraint token is a single keyword in a `#[account(<TOKEN>)]` attribute. // Constraint token is a single keyword in a `#[account(<TOKEN>)]` attribute.
#[allow(clippy::large_enum_variant)]
#[derive(Debug)] #[derive(Debug)]
pub enum ConstraintToken { pub enum ConstraintToken {
Init(Context<ConstraintInit>), Init(Context<ConstraintInit>),
@ -433,6 +436,7 @@ pub struct ConstraintAssociatedSpace {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum PdaKind { pub enum PdaKind {
Program, Program,
Token { owner: Expr, mint: Expr }, Token { owner: Expr, mint: Expr },

View File

@ -76,7 +76,10 @@ pub fn parse_token(stream: ParseStream) -> ParseResult<ConstraintToken> {
} }
_ => { _ => {
stream.parse::<Token![=]>()?; stream.parse::<Token![=]>()?;
let span = ident.span().join(stream.span()).unwrap_or(ident.span()); let span = ident
.span()
.join(stream.span())
.unwrap_or_else(|| ident.span());
match kw.as_str() { match kw.as_str() {
"belongs_to" | "has_one" => ConstraintToken::BelongsTo(Context::new( "belongs_to" | "has_one" => ConstraintToken::BelongsTo(Context::new(
span, span,
@ -173,7 +176,7 @@ pub fn parse_token(stream: ParseStream) -> ParseResult<ConstraintToken> {
auth: stream.parse()?, auth: stream.parse()?,
}, },
)), )),
_ => Err(ParseError::new(ident.span(), "Invalid attribute"))?, _ => return Err(ParseError::new(ident.span(), "Invalid attribute")),
} }
} }
}; };

View File

@ -14,12 +14,11 @@ pub fn parse(strct: &syn::ItemStruct) -> ParseResult<AccountsStruct> {
let instruction_api: Option<Punctuated<Expr, Comma>> = strct let instruction_api: Option<Punctuated<Expr, Comma>> = strct
.attrs .attrs
.iter() .iter()
.filter(|a| { .find(|a| {
a.path a.path
.get_ident() .get_ident()
.map_or(false, |ident| ident == "instruction") .map_or(false, |ident| ident == "instruction")
}) })
.next()
.map(|ix_attr| ix_attr.parse_args_with(Punctuated::<Expr, Comma>::parse_terminated)) .map(|ix_attr| ix_attr.parse_args_with(Punctuated::<Expr, Comma>::parse_terminated))
.transpose()?; .transpose()?;
let fields = match &strct.fields { let fields = match &strct.fields {
@ -68,11 +67,16 @@ pub fn parse_account_field(f: &syn::Field, has_instruction_api: bool) -> ParseRe
} }
fn is_field_primitive(f: &syn::Field) -> ParseResult<bool> { fn is_field_primitive(f: &syn::Field) -> ParseResult<bool> {
let r = match ident_string(f)?.as_str() { let r = matches!(
"ProgramState" | "ProgramAccount" | "CpiAccount" | "Sysvar" | "AccountInfo" ident_string(f)?.as_str(),
| "CpiState" | "Loader" => true, "ProgramState"
_ => false, | "ProgramAccount"
}; | "CpiAccount"
| "Sysvar"
| "AccountInfo"
| "CpiState"
| "Loader"
);
Ok(r) Ok(r)
} }
@ -113,12 +117,12 @@ fn ident_string(f: &syn::Field) -> ParseResult<String> {
} }
fn parse_program_state(path: &syn::Path) -> ParseResult<ProgramStateTy> { fn parse_program_state(path: &syn::Path) -> ParseResult<ProgramStateTy> {
let account_ident = parse_account(&path)?; let account_ident = parse_account(path)?;
Ok(ProgramStateTy { account_ident }) Ok(ProgramStateTy { account_ident })
} }
fn parse_cpi_state(path: &syn::Path) -> ParseResult<CpiStateTy> { fn parse_cpi_state(path: &syn::Path) -> ParseResult<CpiStateTy> {
let account_ident = parse_account(&path)?; let account_ident = parse_account(path)?;
Ok(CpiStateTy { account_ident }) Ok(CpiStateTy { account_ident })
} }
@ -161,20 +165,16 @@ fn parse_account(path: &syn::Path) -> ParseResult<syn::Ident> {
let path_segment = &ty_path.path.segments[0]; let path_segment = &ty_path.path.segments[0];
Ok(path_segment.ident.clone()) Ok(path_segment.ident.clone())
} }
_ => { _ => Err(ParseError::new(
return Err(ParseError::new( args.args[1].span(),
args.args[1].span(), "first bracket argument must be a lifetime",
"first bracket argument must be a lifetime", )),
))
}
} }
} }
_ => { _ => Err(ParseError::new(
return Err(ParseError::new( segments.arguments.span(),
segments.arguments.span(), "expected angle brackets with a lifetime and type",
"expected angle brackets with a lifetime and type", )),
))
}
} }
} }

View File

@ -68,7 +68,7 @@ pub fn parse(program_mod: &syn::ItemMod) -> ParseResult<Option<State>> {
.items .items
.iter() .iter()
.filter_map(|item: &syn::ImplItem| match item { .filter_map(|item: &syn::ImplItem| match item {
syn::ImplItem::Method(m) => match m.sig.ident.to_string() == CTOR_METHOD_NAME { syn::ImplItem::Method(m) => match m.sig.ident == CTOR_METHOD_NAME {
false => None, false => None,
true => Some(m), true => Some(m),
}, },
@ -143,7 +143,7 @@ pub fn parse(program_mod: &syn::ItemMod) -> ParseResult<Option<State>> {
} }
} }
}; };
Ok((m.clone(), ctx_accounts_ident(&ctx_arg)?)) Ok((m.clone(), ctx_accounts_ident(ctx_arg)?))
}) })
.next(); .next();
r.transpose() r.transpose()
@ -159,7 +159,7 @@ pub fn parse(program_mod: &syn::ItemMod) -> ParseResult<Option<State>> {
.items .items
.iter() .iter()
.filter_map(|item| match item { .filter_map(|item| match item {
syn::ImplItem::Method(m) => match m.sig.ident.to_string() != CTOR_METHOD_NAME { syn::ImplItem::Method(m) => match m.sig.ident != CTOR_METHOD_NAME {
false => None, false => None,
true => Some(m), true => Some(m),
}, },
@ -238,12 +238,10 @@ pub fn parse(program_mod: &syn::ItemMod) -> ParseResult<Option<State>> {
}) })
.map(|m: &syn::ImplItemMethod| { .map(|m: &syn::ImplItemMethod| {
match m.sig.inputs.first() { match m.sig.inputs.first() {
None => { None => Err(ParseError::new(
return Err(ParseError::new( m.sig.inputs.span(),
m.sig.inputs.span(), "state methods must have a self argument",
"state methods must have a self argument", )),
))
}
Some(_arg) => { Some(_arg) => {
let mut has_receiver = false; let mut has_receiver = false;
let mut args = m let mut args = m

View File

@ -13,6 +13,7 @@ anchor_lang::solana_program::declare_id!("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9P
#[cfg(feature = "devnet")] #[cfg(feature = "devnet")]
anchor_lang::solana_program::declare_id!("DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY"); anchor_lang::solana_program::declare_id!("DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY");
#[allow(clippy::too_many_arguments)]
pub fn new_order_v3<'info>( pub fn new_order_v3<'info>(
ctx: CpiContext<'_, '_, '_, 'info, NewOrderV3<'info>>, ctx: CpiContext<'_, '_, '_, 'info, NewOrderV3<'info>>,
side: Side, side: Side,
@ -24,7 +25,7 @@ pub fn new_order_v3<'info>(
client_order_id: u64, client_order_id: u64,
limit: u16, limit: u16,
) -> ProgramResult { ) -> ProgramResult {
let referral = ctx.remaining_accounts.iter().next(); let referral = ctx.remaining_accounts.get(0);
let ix = serum_dex::instruction::new_order( let ix = serum_dex::instruction::new_order(
ctx.accounts.market.key, ctx.accounts.market.key,
ctx.accounts.open_orders.key, ctx.accounts.open_orders.key,
@ -60,7 +61,7 @@ pub fn new_order_v3<'info>(
pub fn settle_funds<'info>( pub fn settle_funds<'info>(
ctx: CpiContext<'_, '_, '_, 'info, SettleFunds<'info>>, ctx: CpiContext<'_, '_, '_, 'info, SettleFunds<'info>>,
) -> ProgramResult { ) -> ProgramResult {
let referral = ctx.remaining_accounts.iter().next(); let referral = ctx.remaining_accounts.get(0);
let ix = serum_dex::instruction::settle_funds( let ix = serum_dex::instruction::settle_funds(
&ID, &ID,
ctx.accounts.market.key, ctx.accounts.market.key,

View File

@ -249,14 +249,14 @@ impl Deref for Mint {
pub mod accessor { pub mod accessor {
use super::*; use super::*;
pub fn amount<'info>(account: &AccountInfo<'info>) -> Result<u64, ProgramError> { pub fn amount(account: &AccountInfo) -> Result<u64, ProgramError> {
let bytes = account.try_borrow_data()?; let bytes = account.try_borrow_data()?;
let mut amount_bytes = [0u8; 8]; let mut amount_bytes = [0u8; 8];
amount_bytes.copy_from_slice(&bytes[64..72]); amount_bytes.copy_from_slice(&bytes[64..72]);
Ok(u64::from_le_bytes(amount_bytes)) Ok(u64::from_le_bytes(amount_bytes))
} }
pub fn mint<'info>(account: &AccountInfo<'info>) -> Result<Pubkey, ProgramError> { pub fn mint(account: &AccountInfo) -> Result<Pubkey, ProgramError> {
let bytes = account.try_borrow_data()?; let bytes = account.try_borrow_data()?;
let mut mint_bytes = [0u8; 32]; let mut mint_bytes = [0u8; 32];
mint_bytes.copy_from_slice(&bytes[..32]); mint_bytes.copy_from_slice(&bytes[..32]);