diff --git a/Cargo.lock b/Cargo.lock index 3b8e35ffd..e90229dad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -864,6 +864,26 @@ name = "ordermap" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "paste" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "paste-impl" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "petgraph" version = "0.4.13" @@ -1302,6 +1322,7 @@ dependencies = [ "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "pwd 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2224,6 +2245,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" +"checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49" +"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" "checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" diff --git a/tests/snippets/stdlib_struct.py b/tests/snippets/stdlib_struct.py index e3153882e..e7be196c9 100644 --- a/tests/snippets/stdlib_struct.py +++ b/tests/snippets/stdlib_struct.py @@ -38,3 +38,6 @@ with assert_raises(Exception): data = struct.pack('B2B', 65, 66) data = struct.pack('B1B', 65, 66) + +with assert_raises(Exception): + struct.pack(' bool { } } -fn get_int(vm: &VirtualMachine, arg: &PyObjectRef) -> PyResult { - objint::to_int(vm, arg, &BigInt::from(10)) +macro_rules! make_pack_no_endianess { + ($T:ty) => { + paste::item! { + fn [](vm: &VirtualMachine, arg: &PyObjectRef, data: &mut dyn Write) -> PyResult<()> { + let v = $T::try_from_object(vm, arg.clone())?; + data.[](v).unwrap(); + Ok(()) + } + } + }; } -fn pack_i8(vm: &VirtualMachine, arg: &PyObjectRef, data: &mut dyn Write) -> PyResult<()> { - let v = get_int(vm, arg)?.to_i8().unwrap(); - data.write_i8(v).unwrap(); - Ok(()) +macro_rules! make_pack_with_endianess { + ($T:ty) => { + paste::item! { + fn [](vm: &VirtualMachine, arg: &PyObjectRef, data: &mut dyn Write) -> PyResult<()> + where + Endianness: byteorder::ByteOrder, + { + let v = $T::try_from_object(vm, arg.clone())?; + data.[]::(v).unwrap(); + Ok(()) + } + } + }; } -fn pack_u8(vm: &VirtualMachine, arg: &PyObjectRef, data: &mut dyn Write) -> PyResult<()> { - let v = get_int(vm, arg)?.to_u8().unwrap(); - data.write_u8(v).unwrap(); - Ok(()) -} +make_pack_no_endianess!(i8); +make_pack_no_endianess!(u8); +make_pack_with_endianess!(i16); +make_pack_with_endianess!(u16); +make_pack_with_endianess!(i32); +make_pack_with_endianess!(u32); +make_pack_with_endianess!(i64); +make_pack_with_endianess!(u64); +make_pack_with_endianess!(f32); +make_pack_with_endianess!(f64); fn pack_bool(vm: &VirtualMachine, arg: &PyObjectRef, data: &mut dyn Write) -> PyResult<()> { - if objtype::isinstance(&arg, &vm.ctx.bool_type()) { - let v = if objbool::get_value(arg) { 1 } else { 0 }; - data.write_u8(v).unwrap(); - Ok(()) + let v = if bool::try_from_object(vm, arg.clone())? { + 1 } else { - Err(vm.new_type_error("Expected boolean".to_string())) - } -} - -fn pack_i16( - vm: &VirtualMachine, - arg: &PyObjectRef, - data: &mut dyn Write, -) -> PyResult<()> -where - Endianness: byteorder::ByteOrder, -{ - let v = get_int(vm, arg)?.to_i16().unwrap(); - data.write_i16::(v).unwrap(); + 0 + }; + data.write_u8(v).unwrap(); Ok(()) } -fn pack_u16( - vm: &VirtualMachine, - arg: &PyObjectRef, - data: &mut dyn Write, -) -> PyResult<()> -where - Endianness: byteorder::ByteOrder, -{ - let v = get_int(vm, arg)?.to_u16().unwrap(); - data.write_u16::(v).unwrap(); - Ok(()) -} - -fn pack_i32( - vm: &VirtualMachine, - arg: &PyObjectRef, - data: &mut dyn Write, -) -> PyResult<()> -where - Endianness: byteorder::ByteOrder, -{ - let v = get_int(vm, arg)?.to_i32().unwrap(); - data.write_i32::(v).unwrap(); - Ok(()) -} - -fn pack_u32( - vm: &VirtualMachine, - arg: &PyObjectRef, - data: &mut dyn Write, -) -> PyResult<()> -where - Endianness: byteorder::ByteOrder, -{ - let v = get_int(vm, arg)?.to_u32().unwrap(); - data.write_u32::(v).unwrap(); - Ok(()) -} - -fn pack_i64( - vm: &VirtualMachine, - arg: &PyObjectRef, - data: &mut dyn Write, -) -> PyResult<()> -where - Endianness: byteorder::ByteOrder, -{ - let v = get_int(vm, arg)?.to_i64().unwrap(); - data.write_i64::(v).unwrap(); - Ok(()) -} - -fn pack_u64( - vm: &VirtualMachine, - arg: &PyObjectRef, - data: &mut dyn Write, -) -> PyResult<()> -where - Endianness: byteorder::ByteOrder, -{ - let v = get_int(vm, arg)?.to_u64().unwrap(); - data.write_u64::(v).unwrap(); - Ok(()) -} - -fn pack_f32( - vm: &VirtualMachine, - arg: &PyObjectRef, - data: &mut dyn Write, -) -> PyResult<()> -where - Endianness: byteorder::ByteOrder, -{ - let v = get_float(vm, arg)? as f32; - data.write_f32::(v).unwrap(); - Ok(()) -} - -fn pack_f64( - vm: &VirtualMachine, - arg: &PyObjectRef, - data: &mut dyn Write, -) -> PyResult<()> -where - Endianness: byteorder::ByteOrder, -{ - let v = get_float(vm, arg)?; - data.write_f64::(v).unwrap(); - Ok(()) -} - -fn get_float(vm: &VirtualMachine, arg: &PyObjectRef) -> PyResult { - if objtype::isinstance(&arg, &vm.ctx.float_type()) { - Ok(objfloat::get_value(arg)) - } else { - Err(vm.new_type_error("Expected float".to_string())) - } -} - fn pack_item( vm: &VirtualMachine, code: &FormatCode,