Skip to content

Commit 9e20c1b

Browse files
committed
a convinient way to derive traits
1 parent 0d46a2d commit 9e20c1b

File tree

6 files changed

+58
-4
lines changed

6 files changed

+58
-4
lines changed

program/rust/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ edition = "2021"
77
license = "Apache 2.0"
88
publish = false
99

10+
[build-dependencies]
11+
bindgen = "0.60.1"
12+
1013
[dependencies]
1114
solana-program = "=1.10.29"
15+
borsh = "0.9"
16+
1217

1318
[lib]
1419
crate-type = ["cdylib", "lib"]

program/rust/build.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
mod build_utils;
2+
use bindgen;
3+
use std::collections::HashMap;
4+
use std::vec::Vec;
5+
6+
17
fn main() {
28
println!("cargo:rustc-link-search=../c/target");
9+
10+
let borsh_derives: Vec<String> = vec!["BorshSerialize".to_string(), "BorshDeserialize".to_string()];
11+
12+
let parser = build_utils::DeriveAdderParserCallback{types_to_traits: HashMap::from([
13+
("cmd_hdr", borsh_derives)
14+
//map more struct names to traits here, be sure that the definitions of your traites
15+
//are included in c_oracle_header.rs
16+
])};
17+
18+
//generate and write bindings
19+
let bindings = bindgen::Builder::default().header("./src/bindings.h").parse_callbacks(Box::new(parser)).generate().expect("Unable to generate bindings");
20+
bindings.write_to_file("./bindings.rs").expect("Couldn't write bindings!");
321
}

program/rust/build_utils.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use bindgen;
2+
use std::panic::UnwindSafe;
3+
use std::collections::HashMap;
4+
///This type stores a hashmap from structnames
5+
///to vectors of trait names, and ensures
6+
///that the traits of each struct are added to its
7+
///definition when an instance of this struct
8+
///is provided as a ParseCallback for bindgen
9+
#[derive(Debug)]
10+
pub struct DeriveAdderParserCallback<'a>{
11+
pub types_to_traits: HashMap<&'a str, Vec<String>> ,
12+
}
13+
14+
//this is required to implement the callback trait
15+
impl UnwindSafe for DeriveAdderParserCallback<'_> {}
16+
17+
impl bindgen::callbacks::ParseCallbacks for DeriveAdderParserCallback<'_>{
18+
fn add_derives(&self, _name: &str) -> Vec<String>{
19+
let traits = self.types_to_traits.get(_name);
20+
match traits{
21+
Some(trait_names)=>trait_names.to_vec(),
22+
None => vec![],
23+
}
24+
}
25+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![allow(non_upper_case_globals)]
2+
#![allow(non_camel_case_types)]
3+
#![allow(non_snake_case)]
4+
//All the custom trait imports should go here
5+
use borsh::{BorshSerialize, BorshDeserialize};
6+
//bindings.rs is generated by build.rs to include
7+
//things defined in bindings.h
8+
include!("../bindings.rs");

program/rust/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//c_oracle_header is auto generated by build_bpf.sh
2-
//to reflect the current status of oracle.h
31
mod c_oracle_header;
42

53
//do not link with C during unit tests (which are built in native architecture, unlike libpyth.o)

scripts/build-bpf.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ rm ./target/*-keypair.json
4040

4141
#build Rust and link it with C
4242
cd "${RUST_DIR}"
43-
cargo install bindgen
44-
bindgen ./src/bindings.h -o ./src/c_oracle_header.rs
43+
#cargo install bindgen
44+
#bindgen ./src/bindings.h -o ./src/c_oracle_header.rs
4545
cargo clean
4646
cargo test
4747
cargo clean

0 commit comments

Comments
 (0)