Comments (11)
So to clarify what will happen in v0.5:
impl Buf for Bytes
directly (removeIntoBuf
ofCursor<Self>
)impl Buf for BytesMut
directly (removeIntoBuf
ofCursor<Self>
)impl IntoBuf for &Bytes
to return&[u8]
impl IntoBuf for &BytesMut
to return&[u8]
impl IntoIterator for Bytes
to useslice::Iter
impl IntoIterator for BytesMut
to usevec::IntoIter
Look right?
from bytes.
I also just twitch a bit whenever I see io::Cursor
, I sort of regret adding it to std, it doesn't seem to really pull its weight.
from bytes.
Makes sense. I mostly opted for Cursor
to not add another type.
Another option would be to bring back ByteBuf
or something like that?
from bytes.
I think a local "cursor type" (w/e the name) may be right here, but I wouldn't add it just yet (I don't know what it should look like)
from bytes.
I also just twitch a bit whenever I see io::Cursor, I sort of regret adding it to std, it doesn't seem to really pull its weight.
A bit off topic, but note that I love it being in std, you can easily use it to Read over a buffer. Very interesting when you only offer a io::Read
based API and people want to use it with their memory buffered data (best use case is tests).
from bytes.
Using Cursor
here is definitely a mistake on my part...
std
implements Read
and Write
for &[u8]
and &mut [u8]
respectively. We probably want to follow that pattern and implement Buf
/ BufMut
for &[u8]
and &mut [u8]
.
from bytes.
+1 on this. io::Cursor
complicates no_std
usage. I had to vendor it in to my PR to add no_std
support: #135
Perhaps I should change that PR to just stop using io::Cursor
entirely?
from bytes.
I opened a PR which vendors std::io::Cursor
as buf::Cursor
(while also reducing the position counter size to u32
): #146
I'm not sure that's entirely ideal but I don't see any other path forward here. I need something like it to make progress on #135
from bytes.
Looks bout right.
from bytes.
I am looking at implementing IntoBuf
for BytesMut
, to solve the tokio-io problem. I am trying to understand what needs to happen
Am I reading the issues correctly that you want to get rid of Cursor. Does the replacement implementation you have in mind look like adding a position field to Bytes
and BytesMut
structs?
from bytes.
Never mind, I think I figured out how to do it using the fields of Inner
.
The only problem I ran into is the removal of set_position
. My understanding is that using only the elements of Inner
, advancing the buffer would either be permanent or affect all copies. Is the ability to seek backwards used by anyone?.
With the current design, it would be impossible to seek backwards when in KIND_INLINE
mode anyway because that information is thrown away. The documentation on advance indicates the first bytes are dropped, so the only reason we could rewind is because of extra functionality io::Cursor provided (using extra storage to avoid modifying the original impl Buf
)
Update: I got the tests to pass, but it reveals in my opinion a dubious iterator implementation for Buf that consumes the Buf, emptying it of data. This went unnoticed before because Cursor was wrapping the underlying storage.
diff --git a/src/buf/iter.rs b/src/buf/iter.rs
index 9345c05..389c252 100644
--- a/src/buf/iter.rs
+++ b/src/buf/iter.rs
@@ -76,14 +76,14 @@ impl<T> Iter<T> {
/// ```rust
/// use bytes::{Buf, IntoBuf, BytesMut};
///
- /// let buf = BytesMut::from(&b"abc"[..]).into_buf();
+ /// let buf = BytesMut::from(&b"abc"[..]);
/// let mut iter = buf.iter();
///
/// assert_eq!(iter.next(), Some(b'a'));
///
- /// iter.get_mut().set_position(0);
+ /// iter.get_mut().advance(1);
///
- /// assert_eq!(iter.next(), Some(b'a'));
+ /// assert_eq!(iter.next(), Some(b'c'));
/// ```
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
diff --git a/src/bytes.rs b/src/bytes.rs
index 4650235..979f3fc 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -1516,6 +1516,26 @@ impl BytesMut {
}
}
+impl Buf for BytesMut {
+ #[inline]
+ fn remaining(&self) -> usize {
+ self.len()
+ }
+
+ fn bytes(&self) -> &[u8] {
+ &(self.inner.as_ref())
+ }
+
+ //fn bytes_vec<'b>(&'b self, dst: &mut [IoVec<'b>]) -> usize {
+ // (**self).bytes_vec(dst)
+ //}
+
+ fn advance(&mut self, cnt: usize) {
+ assert!(cnt <= self.inner.as_ref().len(), "cannot advance past `remaining`");
+ unsafe { self.inner.set_start(cnt); }
+ }
+}
+
impl BufMut for BytesMut {
#[inline]
fn remaining_mut(&self) -> usize {
@@ -1561,22 +1581,6 @@ impl BufMut for BytesMut {
}
}
-impl IntoBuf for BytesMut {
- type Buf = Cursor<Self>;
-
- fn into_buf(self) -> Self::Buf {
- Cursor::new(self)
- }
-}
-
-impl<'a> IntoBuf for &'a BytesMut {
- type Buf = Cursor<&'a BytesMut>;
-
- fn into_buf(self) -> Self::Buf {
- Cursor::new(self)
- }
-}
-
impl AsRef<[u8]> for BytesMut {
#[inline]
fn as_ref(&self) -> &[u8] {
@@ -1741,19 +1745,19 @@ impl Clone for BytesMut {
impl IntoIterator for BytesMut {
type Item = u8;
- type IntoIter = Iter<Cursor<BytesMut>>;
+ type IntoIter = Iter<BytesMut>;
fn into_iter(self) -> Self::IntoIter {
- self.into_buf().iter()
+ self.iter()
}
}
-impl<'a> IntoIterator for &'a BytesMut {
+impl<'a> IntoIterator for &'a mut BytesMut {
type Item = u8;
- type IntoIter = Iter<Cursor<&'a BytesMut>>;
+ type IntoIter = Iter<&'a mut BytesMut>;
fn into_iter(self) -> Self::IntoIter {
- self.into_buf().iter()
+ self.iter()
}
}
diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs
index ccc89fa..67ff12c 100644
--- a/tests/test_bytes.rs
+++ b/tests/test_bytes.rs
@@ -181,11 +181,11 @@ fn split_off_to_loop() {
}
{
let mut bytes = BytesMut::from(&s[..]);
- let off = bytes.split_off(i);
+ let mut off = bytes.split_off(i);
assert_eq!(i, bytes.len());
let mut sum = Vec::new();
- sum.extend(&bytes);
- sum.extend(&off);
+ sum.extend(&mut bytes);
+ sum.extend(&mut off);
assert_eq!(&s[..], &sum[..]);
}
{
@@ -199,11 +199,11 @@ fn split_off_to_loop() {
}
{
let mut bytes = BytesMut::from(&s[..]);
- let off = bytes.split_to(i);
+ let mut off = bytes.split_to(i);
assert_eq!(i, off.len());
let mut sum = Vec::new();
- sum.extend(&off);
- sum.extend(&bytes);
+ sum.extend(&mut off);
+ sum.extend(&mut bytes);
assert_eq!(&s[..], &sum[..]);
}
}
from bytes.
Related Issues (20)
- Is there a comparison of `bytes::Bytes` and `std::io::Bytes`/&[u8]`? HOT 2
- Provide APIs or mode that have similar non-panic guarantees to the `untrusted` crate HOT 2
- Any way to convert `HeaderValue` to `Bytes` without copying? HOT 1
- Need to obtain remaining buffer space HOT 1
- Potential to modify ordering for load in bytes.rs and bytes_mut.rs HOT 2
- Feature Request: Default implementations for heap types which support the unstable allocator API HOT 4
- Feature Request: Default implementations for pinned types HOT 2
- Feature Request: Seekable Buffer ("SeekBuf") and cursor/iterator support HOT 2
- `BufMut` does not include safety invariants in trait documentation HOT 1
- Enable shrinking of allocations
- Contradictory allocation behaviour compared to documentation HOT 9
- Confusing documentation around `Arc<[u8]>` compatibility HOT 1
- Should clone benchmark use use `test::blackbox`? HOT 1
- Explicitly guarantee `Bytes` to be immutable HOT 2
- Expose UTF-8 validated string type HOT 2
- Buf::chunks_vectored() is wrong if chunk() isn't the whole buf HOT 3
- Feature request: fallible version of `BytesMut::unsplit` (i.e. make `BytesMut::try_unsplit` public) HOT 2
- Test for unknown --cfg flags in ci
- Splice for BytesMut HOT 2
- Consider replacing Bytes::make_mut by impl From<Bytes> for BytesMut HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bytes.