-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
697 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "encode-derive" | ||
version = "0.1.0" | ||
authors = ["Chris MacNaughton <chris@centaurisolutions.nl>"] | ||
|
||
[dependencies] | ||
syn = "0.11.11" | ||
quote = "0.3.15" | ||
|
||
[lib] | ||
proc-macro = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
|
||
extern crate proc_macro; | ||
extern crate syn; | ||
#[macro_use] | ||
extern crate quote; | ||
|
||
use proc_macro::TokenStream; | ||
|
||
#[proc_macro_derive(Encode, attributes(count))] | ||
pub fn derive_encode(input: TokenStream) -> TokenStream { | ||
// Construct a string representation of the type definition | ||
let s = input.to_string(); | ||
|
||
// Parse the string representation | ||
let ast = syn::parse_derive_input(&s).unwrap(); | ||
|
||
// Build the impl | ||
let gen = impl_encode(&ast); | ||
|
||
// Return the generated impl | ||
gen.parse().unwrap() | ||
} | ||
|
||
fn impl_encode(ast: &syn::DeriveInput) -> quote::Tokens { | ||
let name = &ast.ident; | ||
let fields = match ast.body { | ||
syn::Body::Struct(ref data) => data.fields(), | ||
syn::Body::Enum(_) => panic!("#[derive(Encode)] can only be used with structs"), | ||
}; | ||
let fields = generate_fields(&fields); | ||
quote! { | ||
impl Encode for #name { | ||
fn encode(&self, mut buff: &mut Vec<u8>) -> Result<(), ::std::io::Error> { | ||
#(#fields)* | ||
Ok(()) | ||
} | ||
} | ||
} | ||
|
||
} | ||
|
||
fn generate_fields(fields: &[syn::Field]) -> Vec<quote::Tokens> { | ||
let mut result = Vec::new(); | ||
for field in fields { | ||
let ident = &field.ident; | ||
if field.attrs.iter().any(|f| f.value.name() == "count") { | ||
result.push(quote!{ | ||
VarInt::new(self.#ident.len() as u64).encode(&mut buff)?; | ||
}); | ||
} | ||
result.push(quote!{ | ||
self.#ident.encode(&mut buff)?; | ||
}); | ||
} | ||
result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use Encode; | ||
use VarInt; | ||
use super::TransactionMessage; | ||
|
||
#[derive(Debug, Encode, PartialEq)] | ||
pub struct BlockMessage { | ||
pub version: i32, | ||
pub previous_block: [u8; 32], | ||
pub merkle_root: [u8; 32], | ||
pub timestamp: u32, | ||
pub bits: u32, | ||
pub nonce: u32, | ||
#[count] | ||
pub transactions: Vec<TransactionMessage> | ||
} | ||
|
||
impl BlockMessage { | ||
#[inline] | ||
pub fn len(&self) -> usize { | ||
4usize + // version | ||
32usize + // previous block | ||
32usize + // merkle root | ||
4usize + // timestamp | ||
4usize + // bits | ||
4usize + // nonce | ||
4usize + // count of transactions | ||
self.transactions.iter().map(|i| i.len()).sum::<usize>() // transactions | ||
} | ||
|
||
#[inline] | ||
pub fn name(&self) -> &'static str { | ||
"block" | ||
} | ||
|
||
pub fn new(version: i32, prev_block: &[u8], merkle_root: &[u8], timestamp: u32, | ||
bits: u32, nonce: u32, transactions: Vec<TransactionMessage>) -> BlockMessage { | ||
debug_assert!(prev_block.len() == 32); | ||
let mut a: [u8; 32] = Default::default(); | ||
a.copy_from_slice(&prev_block); | ||
debug_assert!(merkle_root.len() == 32); | ||
let mut b: [u8; 32] = Default::default(); | ||
b.copy_from_slice(&merkle_root); | ||
BlockMessage { | ||
version: version, | ||
previous_block: a, | ||
merkle_root: b, | ||
timestamp: timestamp, | ||
bits: bits, | ||
nonce: nonce, | ||
transactions: transactions, | ||
} | ||
} | ||
} |
Oops, something went wrong.