]> git.proxmox.com Git - rustc.git/blob - vendor/gix-packetline-blocking/src/line/mod.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / vendor / gix-packetline-blocking / src / line / mod.rs
1 use bstr::BStr;
2
3 use crate::{decode, BandRef, Channel, ErrorRef, PacketLineRef, TextRef, ERR_PREFIX};
4
5 impl<'a> PacketLineRef<'a> {
6 /// Return this instance as slice if it's [`Data`][PacketLineRef::Data].
7 pub fn as_slice(&self) -> Option<&'a [u8]> {
8 match self {
9 PacketLineRef::Data(d) => Some(d),
10 PacketLineRef::Flush | PacketLineRef::Delimiter | PacketLineRef::ResponseEnd => None,
11 }
12 }
13 /// Return this instance's [`as_slice()`][PacketLineRef::as_slice()] as [`BStr`].
14 pub fn as_bstr(&self) -> Option<&'a BStr> {
15 self.as_slice().map(Into::into)
16 }
17 /// Interpret this instance's [`as_slice()`][PacketLineRef::as_slice()] as [`ErrorRef`].
18 ///
19 /// This works for any data received in an error [channel][crate::Channel].
20 ///
21 /// Note that this creates an unchecked error using the slice verbatim, which is useful to [serialize it][ErrorRef::write_to()].
22 /// See [`check_error()`][PacketLineRef::check_error()] for a version that assures the error information is in the expected format.
23 pub fn as_error(&self) -> Option<ErrorRef<'a>> {
24 self.as_slice().map(ErrorRef)
25 }
26 /// Check this instance's [`as_slice()`][PacketLineRef::as_slice()] is a valid [`ErrorRef`] and return it.
27 ///
28 /// This works for any data received in an error [channel][crate::Channel].
29 pub fn check_error(&self) -> Option<ErrorRef<'a>> {
30 self.as_slice().and_then(|data| {
31 if data.len() >= ERR_PREFIX.len() && &data[..ERR_PREFIX.len()] == ERR_PREFIX {
32 Some(ErrorRef(&data[ERR_PREFIX.len()..]))
33 } else {
34 None
35 }
36 })
37 }
38 /// Return this instance as text, with the trailing newline truncated if present.
39 pub fn as_text(&self) -> Option<TextRef<'a>> {
40 self.as_slice().map(Into::into)
41 }
42
43 /// Interpret the data in this [`slice`][PacketLineRef::as_slice()] as [`BandRef`] according to the given `kind` of channel.
44 ///
45 /// Note that this is only relevant in a side-band channel.
46 /// See [`decode_band()`][PacketLineRef::decode_band()] in case `kind` is unknown.
47 pub fn as_band(&self, kind: Channel) -> Option<BandRef<'a>> {
48 self.as_slice().map(|d| match kind {
49 Channel::Data => BandRef::Data(d),
50 Channel::Progress => BandRef::Progress(d),
51 Channel::Error => BandRef::Error(d),
52 })
53 }
54
55 /// Decode the band of this [`slice`][PacketLineRef::as_slice()]
56 pub fn decode_band(&self) -> Result<BandRef<'a>, decode::band::Error> {
57 let d = self.as_slice().ok_or(decode::band::Error::NonDataLine)?;
58 Ok(match d[0] {
59 1 => BandRef::Data(&d[1..]),
60 2 => BandRef::Progress(&d[1..]),
61 3 => BandRef::Error(&d[1..]),
62 band => return Err(decode::band::Error::InvalidSideBand { band_id: band }),
63 })
64 }
65 }
66
67 impl<'a> From<&'a [u8]> for TextRef<'a> {
68 fn from(d: &'a [u8]) -> Self {
69 let d = if d[d.len() - 1] == b'\n' { &d[..d.len() - 1] } else { d };
70 TextRef(d)
71 }
72 }
73
74 impl<'a> TextRef<'a> {
75 /// Return this instance's data.
76 pub fn as_slice(&self) -> &'a [u8] {
77 self.0
78 }
79 /// Return this instance's data as [`BStr`].
80 pub fn as_bstr(&self) -> &'a BStr {
81 self.0.into()
82 }
83 }
84
85 #[cfg(all(not(feature = "blocking-io"), feature = "async-io"))]
86 mod async_io;
87 #[cfg(feature = "blocking-io")]
88 mod blocking_io;