Apply clippy rules (#431)
This commit is contained in:
parent
dc6227fc86
commit
1aa019cb0f
|
@ -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
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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))?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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") {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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! {
|
||||||
|
|
|
@ -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")]
|
||||||
|
|
|
@ -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! {
|
||||||
|
|
|
@ -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! {
|
||||||
|
|
|
@ -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! {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
|
@ -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")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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",
|
)),
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
Loading…
Reference in New Issue