gix_transport/client/blocking_io/
bufread_ext.rs1use std::{
2 io,
3 ops::{Deref, DerefMut},
4};
5
6use gix_packetline::{read::ProgressAction, PacketLineRef};
7
8use crate::{
9 client::{Error, MessageKind},
10 Protocol,
11};
12pub type HandleProgress<'a> = Box<dyn FnMut(bool, &[u8]) -> ProgressAction + 'a>;
14
15pub trait ReadlineBufRead: io::BufRead {
21 fn readline(
29 &mut self,
30 ) -> Option<io::Result<Result<gix_packetline::PacketLineRef<'_>, gix_packetline::decode::Error>>>;
31
32 fn readline_str(&mut self, line: &mut String) -> io::Result<usize>;
37}
38
39pub trait ExtendedBufRead<'a>: ReadlineBufRead {
41 fn set_progress_handler(&mut self, handle_progress: Option<HandleProgress<'a>>);
45 fn peek_data_line(&mut self) -> Option<io::Result<Result<&[u8], Error>>>;
48 fn reset(&mut self, version: Protocol);
51 fn stopped_at(&self) -> Option<MessageKind>;
53}
54
55impl<T: ReadlineBufRead + ?Sized> ReadlineBufRead for Box<T> {
56 fn readline(&mut self) -> Option<io::Result<Result<PacketLineRef<'_>, gix_packetline::decode::Error>>> {
57 ReadlineBufRead::readline(self.deref_mut())
58 }
59 fn readline_str(&mut self, line: &mut String) -> io::Result<usize> {
60 ReadlineBufRead::readline_str(self.deref_mut(), line)
61 }
62}
63
64impl<'a, T: ExtendedBufRead<'a> + ?Sized + 'a> ExtendedBufRead<'a> for Box<T> {
65 fn set_progress_handler(&mut self, handle_progress: Option<HandleProgress<'a>>) {
66 self.deref_mut().set_progress_handler(handle_progress);
67 }
68
69 fn peek_data_line(&mut self) -> Option<io::Result<Result<&[u8], Error>>> {
70 self.deref_mut().peek_data_line()
71 }
72
73 fn reset(&mut self, version: Protocol) {
74 self.deref_mut().reset(version);
75 }
76
77 fn stopped_at(&self) -> Option<MessageKind> {
78 self.deref().stopped_at()
79 }
80}
81
82impl<T: io::Read> ReadlineBufRead for gix_packetline::read::WithSidebands<'_, T, fn(bool, &[u8]) -> ProgressAction> {
83 fn readline(&mut self) -> Option<io::Result<Result<PacketLineRef<'_>, gix_packetline::decode::Error>>> {
84 self.read_data_line()
85 }
86
87 fn readline_str(&mut self, line: &mut String) -> io::Result<usize> {
88 self.read_line_to_string(line)
89 }
90}
91
92impl<'a, T: io::Read> ReadlineBufRead for gix_packetline::read::WithSidebands<'a, T, HandleProgress<'a>> {
93 fn readline(&mut self) -> Option<io::Result<Result<PacketLineRef<'_>, gix_packetline::decode::Error>>> {
94 self.read_data_line()
95 }
96
97 fn readline_str(&mut self, line: &mut String) -> io::Result<usize> {
98 self.read_line_to_string(line)
99 }
100}
101
102impl<'a, T: io::Read> ExtendedBufRead<'a> for gix_packetline::read::WithSidebands<'a, T, HandleProgress<'a>> {
103 fn set_progress_handler(&mut self, handle_progress: Option<HandleProgress<'a>>) {
104 self.set_progress_handler(handle_progress);
105 }
106 fn peek_data_line(&mut self) -> Option<io::Result<Result<&[u8], Error>>> {
107 match self.peek_data_line() {
108 Some(Ok(Ok(line))) => Some(Ok(Ok(line))),
109 Some(Ok(Err(err))) => Some(Ok(Err(err.into()))),
110 Some(Err(err)) => Some(Err(err)),
111 None => None,
112 }
113 }
114 fn reset(&mut self, version: Protocol) {
115 match version {
116 Protocol::V0 | Protocol::V1 => self.reset_with(&[gix_packetline::PacketLineRef::Flush]),
117 Protocol::V2 => self.reset_with(&[
118 gix_packetline::PacketLineRef::Delimiter,
119 gix_packetline::PacketLineRef::Flush,
120 ]),
121 }
122 }
123 fn stopped_at(&self) -> Option<MessageKind> {
124 self.stopped_at().map(|l| match l {
125 gix_packetline::PacketLineRef::Flush => MessageKind::Flush,
126 gix_packetline::PacketLineRef::Delimiter => MessageKind::Delimiter,
127 gix_packetline::PacketLineRef::ResponseEnd => MessageKind::ResponseEnd,
128 gix_packetline::PacketLineRef::Data(_) => unreachable!("data cannot be a delimiter"),
129 })
130 }
131}