forked from RustPython/RustPython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbyteslike.rs
More file actions
126 lines (108 loc) · 3.29 KB
/
byteslike.rs
File metadata and controls
126 lines (108 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use crate::builtins::memory::{try_buffer_from_object, BufferRef};
use crate::common::borrow::{BorrowedValue, BorrowedValueMut};
use crate::pyobject::{BorrowValue, PyObjectRef, PyResult, TryFromObject};
use crate::vm::VirtualMachine;
#[derive(Debug)]
pub struct PyBytesLike(BufferRef);
#[derive(Debug)]
pub struct PyRwBytesLike(BufferRef);
impl PyBytesLike {
pub fn with_ref<F, R>(&self, f: F) -> R
where
F: FnOnce(&[u8]) -> R,
{
f(&*self.borrow_value())
}
pub fn len(&self) -> usize {
self.borrow_value().len()
}
pub fn is_empty(&self) -> bool {
self.borrow_value().is_empty()
}
pub fn to_cow(&self) -> std::borrow::Cow<[u8]> {
self.borrow_value().to_vec().into()
}
}
impl PyRwBytesLike {
pub fn with_ref<F, R>(&self, f: F) -> R
where
F: FnOnce(&mut [u8]) -> R,
{
f(&mut *self.borrow_value())
}
pub fn len(&self) -> usize {
self.borrow_value().len()
}
pub fn is_empty(&self) -> bool {
self.borrow_value().is_empty()
}
}
impl PyBytesLike {
pub fn into_buffer(self) -> BufferRef {
self.0
}
}
impl TryFromObject for PyBytesLike {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
let buffer = try_buffer_from_object(vm, &obj)?;
if buffer.get_options().contiguous {
Ok(Self(buffer))
} else {
Err(vm.new_type_error("non-contiguous buffer is not a bytes-like object".to_owned()))
}
}
}
impl<'a> BorrowValue<'a> for PyBytesLike {
type Borrowed = BorrowedValue<'a, [u8]>;
fn borrow_value(&'a self) -> Self::Borrowed {
self.0.as_contiguous().unwrap()
}
}
pub fn try_bytes_like<R>(
vm: &VirtualMachine,
obj: &PyObjectRef,
f: impl FnOnce(&[u8]) -> R,
) -> PyResult<R> {
let buffer = try_buffer_from_object(vm, obj)?;
buffer.as_contiguous().map(|x| f(&*x)).ok_or_else(|| {
vm.new_type_error("non-contiguous buffer is not a bytes-like object".to_owned())
})
}
pub fn try_rw_bytes_like<R>(
vm: &VirtualMachine,
obj: &PyObjectRef,
f: impl FnOnce(&mut [u8]) -> R,
) -> PyResult<R> {
let buffer = try_buffer_from_object(vm, obj)?;
buffer
.as_contiguous_mut()
.map(|mut x| f(&mut *x))
.ok_or_else(|| vm.new_type_error("buffer is not a read-write bytes-like object".to_owned()))
}
impl PyRwBytesLike {
pub fn new(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<Self> {
let buffer = try_buffer_from_object(vm, &obj)?;
let options = buffer.get_options();
if !options.contiguous {
Err(vm.new_type_error("non-contiguous buffer is not a bytes-like object".to_owned()))
} else if options.readonly {
Err(vm.new_type_error("buffer is not a read-write bytes-like object".to_owned()))
} else {
Ok(Self(buffer))
}
}
pub fn into_buffer(self) -> BufferRef {
self.0
}
}
impl TryFromObject for PyRwBytesLike {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
Self::new(vm, &obj)
}
}
impl<'a> BorrowValue<'a> for PyRwBytesLike {
type Borrowed = BorrowedValueMut<'a, [u8]>;
fn borrow_value(&'a self) -> Self::Borrowed {
self.0.as_contiguous_mut().unwrap()
}
}