1
1
use super :: super :: pyobject:: {
2
- AttributeProtocol , PyContext , PyFuncArgs , PyObjectKind , PyObjectRef , PyResult , TypeProtocol ,
2
+ AttributeProtocol , PyContext , PyFuncArgs , PyObject , PyObjectKind , PyObjectRef , PyResult ,
3
+ TypeProtocol ,
3
4
} ;
4
5
use super :: super :: vm:: VirtualMachine ;
5
6
use super :: objint;
6
- use super :: objlist;
7
7
use super :: objtype;
8
8
use num_traits:: ToPrimitive ;
9
+ use std:: cell:: Ref ;
10
+ use std:: ops:: Deref ;
9
11
// Binary data support
10
12
11
13
// Fill bytes class methods:
12
14
pub fn init ( context : & PyContext ) {
13
15
let ref bytes_type = context. bytes_type ;
14
16
bytes_type. set_attr ( "__eq__" , context. new_rustfunc ( bytes_eq) ) ;
15
- bytes_type. set_attr ( "__init__ " , context. new_rustfunc ( bytes_init ) ) ;
17
+ bytes_type. set_attr ( "__new__ " , context. new_rustfunc ( bytes_new ) ) ;
16
18
bytes_type. set_attr ( "__repr__" , context. new_rustfunc ( bytes_repr) ) ;
17
19
}
18
20
19
- // __init__ (store value into objectkind)
20
- fn bytes_init ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
21
+ fn bytes_new ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
21
22
arg_check ! (
22
23
vm,
23
24
args,
24
- required = [ ( zelf, Some ( vm. ctx. bytes_type( ) ) ) , ( arg, None ) ]
25
+ required = [ ( cls, None ) ] ,
26
+ optional = [ ( val_option, None ) ]
25
27
) ;
26
- let val = if objtype:: isinstance ( arg, & vm. ctx . list_type ( ) ) {
28
+ if !objtype:: issubclass ( cls, & vm. ctx . bytes_type ( ) ) {
29
+ return Err ( vm. new_type_error ( format ! ( "{:?} is not a subtype of bytes" , cls) ) ) ;
30
+ }
31
+
32
+ // Create bytes data:
33
+ let value = if let Some ( ival) = val_option {
34
+ let elements = vm. extract_elements ( ival) ?;
27
35
let mut data_bytes = vec ! [ ] ;
28
- for elem in objlist :: get_elements ( arg ) . iter ( ) {
36
+ for elem in elements . iter ( ) {
29
37
let v = objint:: to_int ( vm, elem, 10 ) ?;
30
38
data_bytes. push ( v. to_u8 ( ) . unwrap ( ) ) ;
31
39
}
32
40
data_bytes
41
+ // return Err(vm.new_type_error("Cannot construct bytes".to_string()));
33
42
} else {
34
- return Err ( vm . new_type_error ( "Cannot construct bytes" . to_string ( ) ) ) ;
43
+ vec ! [ ]
35
44
} ;
36
- set_value ( zelf, val) ;
37
- Ok ( vm. get_none ( ) )
45
+
46
+ Ok ( PyObject :: new (
47
+ PyObjectKind :: Bytes { value : value } ,
48
+ cls. clone ( ) ,
49
+ ) )
38
50
}
39
51
40
52
fn bytes_eq ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -45,29 +57,27 @@ fn bytes_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
45
57
) ;
46
58
47
59
let result = if objtype:: isinstance ( b, & vm. ctx . bytes_type ( ) ) {
48
- get_value ( a) == get_value ( b)
60
+ get_value ( a) . to_vec ( ) == get_value ( b) . to_vec ( )
49
61
} else {
50
62
false
51
63
} ;
52
64
Ok ( vm. ctx . new_bool ( result) )
53
65
}
54
66
55
- pub fn get_value ( obj : & PyObjectRef ) -> Vec < u8 > {
56
- if let PyObjectKind :: Bytes { value } = & obj. borrow ( ) . kind {
57
- value. clone ( )
58
- } else {
59
- panic ! ( "Inner error getting int {:?}" , obj) ;
60
- }
61
- }
62
-
63
- fn set_value ( obj : & PyObjectRef , value : Vec < u8 > ) {
64
- obj. borrow_mut ( ) . kind = PyObjectKind :: Bytes { value } ;
67
+ pub fn get_value < ' a > ( obj : & ' a PyObjectRef ) -> impl Deref < Target = Vec < u8 > > + ' a {
68
+ Ref :: map ( obj. borrow ( ) , |py_obj| {
69
+ if let PyObjectKind :: Bytes { ref value } = py_obj. kind {
70
+ value
71
+ } else {
72
+ panic ! ( "Inner error getting int {:?}" , obj) ;
73
+ }
74
+ } )
65
75
}
66
76
67
77
fn bytes_repr ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
68
78
arg_check ! ( vm, args, required = [ ( obj, Some ( vm. ctx. bytes_type( ) ) ) ] ) ;
69
79
let data = get_value ( obj) ;
70
- let data: Vec < String > = data. into_iter ( ) . map ( |b| format ! ( "\\ x{:02x}" , b) ) . collect ( ) ;
80
+ let data: Vec < String > = data. iter ( ) . map ( |b| format ! ( "\\ x{:02x}" , b) ) . collect ( ) ;
71
81
let data = data. join ( "" ) ;
72
82
Ok ( vm. new_str ( format ! ( "b'{}'" , data) ) )
73
83
}
0 commit comments