@@ -13,12 +13,10 @@ use std::io::{Cursor, Read, Write};
1313use std:: iter:: Peekable ;
1414
1515use byteorder:: { ReadBytesExt , WriteBytesExt } ;
16- use num_bigint:: BigInt ;
17- use num_traits:: ToPrimitive ;
1816
1917use crate :: function:: PyFuncArgs ;
20- use crate :: obj:: { objbool , objbytes, objfloat , objint , objstr, objtype} ;
21- use crate :: pyobject:: { PyObjectRef , PyResult } ;
18+ use crate :: obj:: { objbytes, objstr, objtype} ;
19+ use crate :: pyobject:: { PyObjectRef , PyResult , TryFromObject } ;
2220use crate :: VirtualMachine ;
2321
2422#[ derive( Debug ) ]
@@ -130,144 +128,54 @@ fn is_supported_format_character(c: char) -> bool {
130128 }
131129}
132130
133- fn get_int ( vm : & VirtualMachine , arg : & PyObjectRef ) -> PyResult < BigInt > {
134- objint:: to_int ( vm, arg, & BigInt :: from ( 10 ) )
135- }
136-
137- fn pack_i8 ( vm : & VirtualMachine , arg : & PyObjectRef , data : & mut dyn Write ) -> PyResult < ( ) > {
138- let v = get_int ( vm, arg) ?. to_i8 ( ) . unwrap ( ) ;
139- data. write_i8 ( v) . unwrap ( ) ;
140- Ok ( ( ) )
131+ macro_rules! make_pack_no_endianess {
132+ ( $T: ty) => {
133+ paste:: item! {
134+ fn [ <pack_ $T>] ( vm: & VirtualMachine , arg: & PyObjectRef , data: & mut dyn Write ) -> PyResult <( ) > {
135+ let v = $T:: try_from_object( vm, arg. clone( ) ) ?;
136+ data. [ <write_$T>] ( v) . unwrap( ) ;
137+ Ok ( ( ) )
138+ }
139+ }
140+ } ;
141+ }
142+
143+ macro_rules! make_pack_with_endianess {
144+ ( $T: ty) => {
145+ paste:: item! {
146+ fn [ <pack_ $T>] <Endianness >( vm: & VirtualMachine , arg: & PyObjectRef , data: & mut dyn Write ) -> PyResult <( ) >
147+ where
148+ Endianness : byteorder:: ByteOrder ,
149+ {
150+ let v = $T:: try_from_object( vm, arg. clone( ) ) ?;
151+ data. [ <write_$T>] :: <Endianness >( v) . unwrap( ) ;
152+ Ok ( ( ) )
153+ }
154+ }
155+ } ;
141156}
142157
143- fn pack_u8 ( vm : & VirtualMachine , arg : & PyObjectRef , data : & mut dyn Write ) -> PyResult < ( ) > {
144- let v = get_int ( vm, arg) ?. to_u8 ( ) . unwrap ( ) ;
145- data. write_u8 ( v) . unwrap ( ) ;
146- Ok ( ( ) )
147- }
158+ make_pack_no_endianess ! ( i8 ) ;
159+ make_pack_no_endianess ! ( u8 ) ;
160+ make_pack_with_endianess ! ( i16 ) ;
161+ make_pack_with_endianess ! ( u16 ) ;
162+ make_pack_with_endianess ! ( i32 ) ;
163+ make_pack_with_endianess ! ( u32 ) ;
164+ make_pack_with_endianess ! ( i64 ) ;
165+ make_pack_with_endianess ! ( u64 ) ;
166+ make_pack_with_endianess ! ( f32 ) ;
167+ make_pack_with_endianess ! ( f64 ) ;
148168
149169fn pack_bool ( vm : & VirtualMachine , arg : & PyObjectRef , data : & mut dyn Write ) -> PyResult < ( ) > {
150- if objtype:: isinstance ( & arg, & vm. ctx . bool_type ( ) ) {
151- let v = if objbool:: get_value ( arg) { 1 } else { 0 } ;
152- data. write_u8 ( v) . unwrap ( ) ;
153- Ok ( ( ) )
170+ let v = if bool:: try_from_object ( vm, arg. clone ( ) ) ? {
171+ 1
154172 } else {
155- Err ( vm. new_type_error ( "Expected boolean" . to_string ( ) ) )
156- }
157- }
158-
159- fn pack_i16 < Endianness > (
160- vm : & VirtualMachine ,
161- arg : & PyObjectRef ,
162- data : & mut dyn Write ,
163- ) -> PyResult < ( ) >
164- where
165- Endianness : byteorder:: ByteOrder ,
166- {
167- let v = get_int ( vm, arg) ?. to_i16 ( ) . unwrap ( ) ;
168- data. write_i16 :: < Endianness > ( v) . unwrap ( ) ;
169- Ok ( ( ) )
170- }
171-
172- fn pack_u16 < Endianness > (
173- vm : & VirtualMachine ,
174- arg : & PyObjectRef ,
175- data : & mut dyn Write ,
176- ) -> PyResult < ( ) >
177- where
178- Endianness : byteorder:: ByteOrder ,
179- {
180- let v = get_int ( vm, arg) ?. to_u16 ( ) . unwrap ( ) ;
181- data. write_u16 :: < Endianness > ( v) . unwrap ( ) ;
182- Ok ( ( ) )
183- }
184-
185- fn pack_i32 < Endianness > (
186- vm : & VirtualMachine ,
187- arg : & PyObjectRef ,
188- data : & mut dyn Write ,
189- ) -> PyResult < ( ) >
190- where
191- Endianness : byteorder:: ByteOrder ,
192- {
193- let v = get_int ( vm, arg) ?. to_i32 ( ) . unwrap ( ) ;
194- data. write_i32 :: < Endianness > ( v) . unwrap ( ) ;
195- Ok ( ( ) )
196- }
197-
198- fn pack_u32 < Endianness > (
199- vm : & VirtualMachine ,
200- arg : & PyObjectRef ,
201- data : & mut dyn Write ,
202- ) -> PyResult < ( ) >
203- where
204- Endianness : byteorder:: ByteOrder ,
205- {
206- let v = get_int ( vm, arg) ?. to_u32 ( ) . unwrap ( ) ;
207- data. write_u32 :: < Endianness > ( v) . unwrap ( ) ;
208- Ok ( ( ) )
209- }
210-
211- fn pack_i64 < Endianness > (
212- vm : & VirtualMachine ,
213- arg : & PyObjectRef ,
214- data : & mut dyn Write ,
215- ) -> PyResult < ( ) >
216- where
217- Endianness : byteorder:: ByteOrder ,
218- {
219- let v = get_int ( vm, arg) ?. to_i64 ( ) . unwrap ( ) ;
220- data. write_i64 :: < Endianness > ( v) . unwrap ( ) ;
221- Ok ( ( ) )
222- }
223-
224- fn pack_u64 < Endianness > (
225- vm : & VirtualMachine ,
226- arg : & PyObjectRef ,
227- data : & mut dyn Write ,
228- ) -> PyResult < ( ) >
229- where
230- Endianness : byteorder:: ByteOrder ,
231- {
232- let v = get_int ( vm, arg) ?. to_u64 ( ) . unwrap ( ) ;
233- data. write_u64 :: < Endianness > ( v) . unwrap ( ) ;
234- Ok ( ( ) )
235- }
236-
237- fn pack_f32 < Endianness > (
238- vm : & VirtualMachine ,
239- arg : & PyObjectRef ,
240- data : & mut dyn Write ,
241- ) -> PyResult < ( ) >
242- where
243- Endianness : byteorder:: ByteOrder ,
244- {
245- let v = get_float ( vm, arg) ? as f32 ;
246- data. write_f32 :: < Endianness > ( v) . unwrap ( ) ;
247- Ok ( ( ) )
248- }
249-
250- fn pack_f64 < Endianness > (
251- vm : & VirtualMachine ,
252- arg : & PyObjectRef ,
253- data : & mut dyn Write ,
254- ) -> PyResult < ( ) >
255- where
256- Endianness : byteorder:: ByteOrder ,
257- {
258- let v = get_float ( vm, arg) ?;
259- data. write_f64 :: < Endianness > ( v) . unwrap ( ) ;
173+ 0
174+ } ;
175+ data. write_u8 ( v) . unwrap ( ) ;
260176 Ok ( ( ) )
261177}
262178
263- fn get_float ( vm : & VirtualMachine , arg : & PyObjectRef ) -> PyResult < f64 > {
264- if objtype:: isinstance ( & arg, & vm. ctx . float_type ( ) ) {
265- Ok ( objfloat:: get_value ( arg) )
266- } else {
267- Err ( vm. new_type_error ( "Expected float" . to_string ( ) ) )
268- }
269- }
270-
271179fn pack_item < Endianness > (
272180 vm : & VirtualMachine ,
273181 code : & FormatCode ,
0 commit comments