Skip to content

Basic error_chain compatibility #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions packed_struct/src/packing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ pub enum PackingError {
BufferSizeMismatch { expected: usize, actual: usize }
}

impl Display for PackingError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}

#[cfg(feature="std")]
impl ::std::error::Error for PackingError {
fn description(&self) -> &str {
match *self {
PackingError::InvalidValue => "Invalid value",
PackingError::BitsError => "Bits error",
PackingError::BufferTooSmall => "Buffer too small",
PackingError::BufferSizeMismatch { .. } => "Buffer size mismatched",
PackingError::NotImplemented => "Not implemented"
}
}
}


macro_rules! packing_slice {
($T: path; $num_bytes: expr) => (
Expand Down
9 changes: 9 additions & 0 deletions packed_struct_codegen/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ pub fn collections_prefix() -> syn::Ty {
syn::parse_type("::collections").unwrap()
}

#[cfg(feature="std")]
pub fn result_type() -> syn::Ty {
syn::parse_type("::std::result::Result").expect("result type parse error")
}

#[cfg(not(feature="std"))]
pub fn result_type() -> syn::Ty {
syn::parse_type("::core::result::Result").expect("result type parse error")
}



Expand Down
15 changes: 9 additions & 6 deletions packed_struct_codegen/src/pack_codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ pub fn derive_pack(parsed: &PackStruct) -> quote::Tokens {

}

let result_ty = result_type();

quote! {
#type_documentation
impl #impl_generics ::packed_struct::PackedStruct<[u8; #num_bytes]> for #name #ty_generics #where_clause {
Expand All @@ -106,7 +108,7 @@ pub fn derive_pack(parsed: &PackStruct) -> quote::Tokens {

#[inline]
#[allow(unused_imports, unused_parens)]
fn unpack(src: &[u8; #num_bytes]) -> Result<#name, ::packed_struct::PackingError> {
fn unpack(src: &[u8; #num_bytes]) -> #result_ty <#name, ::packed_struct::PackingError> {
use ::packed_struct::*;

#(#unpack_fields)*
Expand All @@ -127,7 +129,7 @@ pub fn derive_pack(parsed: &PackStruct) -> quote::Tokens {
impl #impl_generics ::packed_struct::PackedStructSlice for #name #ty_generics #where_clause {
#[inline]
#[allow(unused_imports)]
fn pack_to_slice(&self, output: &mut [u8]) -> Result<(), ::packed_struct::PackingError> {
fn pack_to_slice(&self, output: &mut [u8]) -> #result_ty <(), ::packed_struct::PackingError> {
use ::packed_struct::*;

if output.len() != #num_bytes {
Expand All @@ -140,7 +142,7 @@ pub fn derive_pack(parsed: &PackStruct) -> quote::Tokens {

#[inline]
#[allow(unused_imports)]
fn unpack_from_slice(src: &[u8]) -> Result<Self, ::packed_struct::PackingError> {
fn unpack_from_slice(src: &[u8]) -> #result_ty <Self, ::packed_struct::PackingError> {
use ::packed_struct::*;

if src.len() != #num_bytes {
Expand Down Expand Up @@ -325,6 +327,7 @@ fn pack_field(name: &syn::Ident, field: &FieldRegular) -> quote::Tokens {
fn unpack_field(field: &FieldRegular) -> quote::Tokens {
let wrappers: Vec<_> = field.serialization_wrappers.iter().rev().cloned().collect();

let result_ty = result_type();
let mut unpack = quote! { bytes };

let mut i = 0;
Expand All @@ -336,7 +339,7 @@ fn unpack_field(field: &FieldRegular) -> quote::Tokens {
use ::packed_struct::types::*;
use ::packed_struct::types::bits::*;

let res: Result<#endian <_, _, #integer >, PackingError> = <#endian <_, _, _>>::unpack(& #unpack );
let res: #result_ty <#endian <_, _, #integer >, PackingError> = <#endian <_, _, _>>::unpack(& #unpack );
let unpacked = try!(res);
**unpacked
};
Expand All @@ -361,7 +364,7 @@ fn unpack_field(field: &FieldRegular) -> quote::Tokens {
use ::packed_struct::types::*;
use ::packed_struct::types::bits::*;

let res: Result<#endian <_, _, #integer_ty >, PackingError> = <#endian <_, _, #integer_ty >>::unpack(& #unpack );
let res: #result_ty <#endian <_, _, #integer_ty >, PackingError> = <#endian <_, _, #integer_ty >>::unpack(& #unpack );
let unpacked = try!(res);
*unpacked
};
Expand All @@ -383,4 +386,4 @@ fn unpack_field(field: &FieldRegular) -> quote::Tokens {
}

unpack
}
}
3 changes: 2 additions & 1 deletion packed_struct_codegen/src/pack_codegen_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub fn struct_runtime_formatter(parsed: &PackStruct) -> quote::Tokens {
}

let num_fields = debug_fields.len();
let result_ty = result_type();

quote! {
#[doc(hidden)]
Expand All @@ -67,7 +68,7 @@ pub fn struct_runtime_formatter(parsed: &PackStruct) -> quote::Tokens {

#[allow(unused_imports)]
impl #impl_generics ::packed_struct::debug_fmt::PackedStructDebug for #name #ty_generics #where_clause {
fn fmt_fields(&self, fmt: &mut #stdlib_prefix::fmt::Formatter) -> Result<(), #stdlib_prefix::fmt::Error> {
fn fmt_fields(&self, fmt: &mut #stdlib_prefix::fmt::Formatter) -> #result_ty <(), #stdlib_prefix::fmt::Error> {
use ::packed_struct::PackedStruct;

let fields = #debug_fields_fn(self);
Expand Down
1 change: 1 addition & 0 deletions packed_struct_tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ publish = false
[dependencies]
packed_struct = "^0.2.0"
packed_struct_codegen = "^0.2.0"
error-chain = "0.11.0"
69 changes: 69 additions & 0 deletions packed_struct_tests/tests/packing_issue_10.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
extern crate packed_struct;
#[macro_use]
extern crate packed_struct_codegen;

#[macro_use]
extern crate error_chain;

mod errors {
error_chain! {
foreign_links {
PackedStruct(::packed_struct::PackingError);
}
}
}

use errors::*;

use packed_struct::prelude::*;

#[derive(Debug, PackedStruct)]
#[packed_struct(bit_numbering = "msb0")]
pub struct LedDriverConfig {
#[packed_field(bits = "46:47")]
lodvth: Integer<u8, ::packed_bits::Bits2>,
#[packed_field(bits = "44:45")]
sel_td0: Integer<u8, ::packed_bits::Bits2>,
#[packed_field(bits = "43")]
sel_gdly: Integer<u8, ::packed_bits::Bits1>,
#[packed_field(bits = "42")]
xrefresh: Integer<u8, ::packed_bits::Bits1>,
#[packed_field(bits = "41")]
sel_gck_edge: Integer<u8, ::packed_bits::Bits1>,
#[packed_field(bits = "40")]
sel_pchg: Integer<u8, ::packed_bits::Bits1>,
#[packed_field(bits = "39")]
espwm: Integer<u8, ::packed_bits::Bits1>,
#[packed_field(bits = "38")]
lgse3: Integer<u8, ::packed_bits::Bits1>,
#[packed_field(bits = "37")]
sel_sck_edge: Integer<u8, ::packed_bits::Bits1>,
#[packed_field(bits = "34:36")]
lgse1: Integer<u8, ::packed_bits::Bits3>,
#[packed_field(bits = "25:33", endian = "msb")]
ccb: Integer<u16, ::packed_bits::Bits9>,
#[packed_field(bits = "16:24", endian = "msb")]
ccg: Integer<u16, ::packed_bits::Bits9>,
#[packed_field(bits = "7:15", endian = "msb")]
ccr: Integer<u16, ::packed_bits::Bits9>,
#[packed_field(bits = "4:6")]
bc: Integer<u8, ::packed_bits::Bits3>,
#[packed_field(bits = "3")]
poker_trans_mode: Integer<u8, ::packed_bits::Bits1>,
#[packed_field(bits = "0:2")]
lgse2: Integer<u8, ::packed_bits::Bits3>,
}

#[test]
#[cfg(test)]
fn test_packed_struct_issue_10() {
run().unwrap();
}

fn run() -> Result<()> {
let data = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF];
let unpacked = LedDriverConfig::unpack(&data)
.chain_err(|| "unable to unpack LED driver config")?;

Ok(())
}