Add stream_id accessors to public API types (#292)
Problem: Applications may want to access the underlying h2 stream ID for diagnostics, etc. Stream IDs were not previously exposed in public APIs. Solution: Added a new public `share::StreamId` type, which has a more restricted API than the internal `frame::StreamId` type. The public API types `SendStream`, `RecvStream`, `ReleaseCapacity`, `client::ResponseFuture`, and `server::SendResponse` now all have `stream_id` methods which return the stream ID of the corresponding stream. Closes #289. Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This commit is contained in:
@@ -1,6 +1,16 @@
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use std::u32;
|
||||
|
||||
/// A stream identifier, as described in [Section 5.1.1] of RFC 7540.
|
||||
///
|
||||
/// Streams are identified with an unsigned 31-bit integer. Streams
|
||||
/// initiated by a client MUST use odd-numbered stream identifiers; those
|
||||
/// initiated by the server MUST use even-numbered stream identifiers. A
|
||||
/// stream identifier of zero (0x0) is used for connection control
|
||||
/// messages; the stream identifier of zero cannot be used to establish a
|
||||
/// new stream.
|
||||
///
|
||||
/// [Section 5.1.1]: https://tools.ietf.org/html/rfc7540#section-5.1.1
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub struct StreamId(u32);
|
||||
|
||||
@@ -10,8 +20,10 @@ pub struct StreamIdOverflow;
|
||||
const STREAM_ID_MASK: u32 = 1 << 31;
|
||||
|
||||
impl StreamId {
|
||||
/// Stream ID 0.
|
||||
pub const ZERO: StreamId = StreamId(0);
|
||||
|
||||
/// The maximum allowed stream ID.
|
||||
pub const MAX: StreamId = StreamId(u32::MAX >> 1);
|
||||
|
||||
/// Parse the stream ID
|
||||
@@ -25,25 +37,34 @@ impl StreamId {
|
||||
(StreamId(unpacked & !STREAM_ID_MASK), flag)
|
||||
}
|
||||
|
||||
/// Returns true if this stream ID corresponds to a stream that
|
||||
/// was initiated by the client.
|
||||
pub fn is_client_initiated(&self) -> bool {
|
||||
let id = self.0;
|
||||
id != 0 && id % 2 == 1
|
||||
}
|
||||
|
||||
/// Returns true if this stream ID corresponds to a stream that
|
||||
/// was initiated by the server.
|
||||
pub fn is_server_initiated(&self) -> bool {
|
||||
let id = self.0;
|
||||
id != 0 && id % 2 == 0
|
||||
}
|
||||
|
||||
/// Return a new `StreamId` for stream 0.
|
||||
#[inline]
|
||||
pub fn zero() -> StreamId {
|
||||
StreamId::ZERO
|
||||
}
|
||||
|
||||
/// Returns true if this stream ID is zero.
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.0 == 0
|
||||
}
|
||||
|
||||
/// Returns the next stream ID initiated by the same peer as this stream
|
||||
/// ID, or an error if incrementing this stream ID would overflow the
|
||||
/// maximum.
|
||||
pub fn next_id(&self) -> Result<StreamId, StreamIdOverflow> {
|
||||
let next = self.0 + 2;
|
||||
if next > StreamId::MAX.0 {
|
||||
|
||||
Reference in New Issue
Block a user