History

[git-transport] all non-IO types are now shared

Sebastian Thiel committed 5 years ago

Commit 209c7801 parent 95e68013 files · +133 −121Browse files

Unified · Split

3 files
  1. git-transport/src/client/blocking_io/connect.rs +0 −39
  2. git-transport/src/client/blocking_io/mod.rs +43 −81
  3. git-transport/src/client/mod.rs +90 −1
git-transport/src/client/blocking_io/connect.rs+0−39
@@ -33,45 +33,6 @@ quick_error! { · 32 unmodified lines
33 }33 }
34}34}
35 35
36mod box_impl {
37 use crate::{
38 client::{self, Error, Identity, MessageKind, RequestWriter, SetServiceResponse, WriteMode},
39 Protocol, Service,
40 };
41 use std::ops::{Deref, DerefMut};
42
43 // Would be nice if the box implementation could auto-forward to all implemented traits.
44 impl<T: client::Transport + ?Sized> client::Transport for Box<T> {
45 fn handshake(&mut self, service: Service) -> Result<SetServiceResponse<'_>, Error> {
46 self.deref_mut().handshake(service)
47 }
48
49 fn set_identity(&mut self, identity: Identity) -> Result<(), Error> {
50 self.deref_mut().set_identity(identity)
51 }
52
53 fn request(&mut self, write_mode: WriteMode, on_into_read: MessageKind) -> Result<RequestWriter<'_>, Error> {
54 self.deref_mut().request(write_mode, on_into_read)
55 }
56
57 fn close(&mut self) -> Result<(), Error> {
58 self.deref_mut().close()
59 }
60
61 fn to_url(&self) -> String {
62 self.deref().to_url()
63 }
64
65 fn desired_protocol_version(&self) -> Protocol {
66 self.deref().desired_protocol_version()
67 }
68
69 fn is_stateful(&self) -> bool {
70 self.deref().is_stateful()
71 }
72 }
73}
74
75/// A general purpose connector connecting to a repository identified by the given `url`.36/// A general purpose connector connecting to a repository identified by the given `url`.
76///37///
77/// This includes connections to38/// This includes connections to
git-transport/src/client/blocking_io/mod.rs+43−81
@@ -10,49 +10,15 @@ pub(crate) mod request; · 9 unmodified lines
10///10///
11pub mod ssh;11pub mod ssh;
12 12
13use crate::{Protocol, Service};13use crate::{
14 client::{capabilities, Capabilities, Error, Identity, MessageKind, WriteMode},
15 Protocol, Service,
16};
14use bstr::BString;17use bstr::BString;
15use std::{io, io::Write};18use std::{io, io::Write};
16 19
17use crate::client::{capabilities, Capabilities};
18use request::{ExtendedBufRead, RequestWriter};20use request::{ExtendedBufRead, RequestWriter};
19 21
20#[cfg(feature = "http-client-curl")]
21type HttpError = http::Error;
22#[cfg(not(feature = "http-client-curl"))]
23type HttpError = std::convert::Infallible;
24
25/// The error used in most methods of the [`client`][crate::client] module
26#[derive(thiserror::Error, Debug)]
27#[allow(missing_docs)]
28pub enum Error {
29 #[error("An IO error occurred when talking to the server")]
30 Io {
31 #[from]
32 err: io::Error,
33 },
34 #[error("Capabilities could not be parsed")]
35 Capabilities {
36 #[from]
37 err: capabilities::Error,
38 },
39 #[error("A packet line could not be decoded")]
40 LineDecode {
41 #[from]
42 err: git_packetline::decode::Error,
43 },
44 #[error("A {0} line was expected, but there was none")]
45 ExpectedLine(&'static str),
46 #[error("Expected a data line, but got a delimiter")]
47 ExpectedDataLine,
48 #[error("The transport layer does not support authentication")]
49 AuthenticationUnsupported,
50 #[error("The transport layer refuses to use a given identity: {0}")]
51 AuthenticationRefused(&'static str),
52 #[error(transparent)]
53 Http(#[from] HttpError),
54}
55
56/// The response of the [`handshake()`][Transport::handshake()] method.22/// The response of the [`handshake()`][Transport::handshake()] method.
57pub struct SetServiceResponse<'a> {23pub struct SetServiceResponse<'a> {
58 /// The protocol the service can provide. May be different from the requested one24 /// The protocol the service can provide. May be different from the requested one
@@ -63,49 +29,6 @@ pub struct SetServiceResponse<'a> { · 4 unmodified lines
63 pub refs: Option<Box<dyn io::BufRead + 'a>>,29 pub refs: Option<Box<dyn io::BufRead + 'a>>,
64}30}
65 31
66/// Configure how the [`RequestWriter`] behaves when writing bytes.
67#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
68#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
69pub enum WriteMode {
70 /// Each [write()][Write::write()] call writes the bytes verbatim as one or more packet lines.
71 Binary,
72 /// Each [write()][Write::write()] call assumes text in the input, assures a trailing newline and writes it as single packet line.
73 OneLfTerminatedLinePerWriteCall,
74}
75
76impl Default for WriteMode {
77 fn default() -> Self {
78 WriteMode::OneLfTerminatedLinePerWriteCall
79 }
80}
81
82/// The kind of packet line to write when transforming a [`RequestWriter`] into an [`ExtendedBufRead`].
83#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
84#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
85pub enum MessageKind {
86 /// A `flush` packet.
87 Flush,
88 /// A V2 delimiter.
89 Delimiter,
90 /// The end of a response.
91 ResponseEnd,
92 /// The given text.
93 Text(&'static [u8]),
94}
95
96#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
97#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
98/// An identity for use when authenticating the transport layer.
99pub enum Identity {
100 /// An account based identity
101 Account {
102 /// The user's name
103 username: String,
104 /// The user's password
105 password: String,
106 },
107}
108
109/// All methods provided here must be called in the correct order according to the [communication protocol][Protocol]32/// All methods provided here must be called in the correct order according to the [communication protocol][Protocol]
110/// used to connect to them.33/// used to connect to them.
111/// It does, however, know just enough to be able to provide a higher-level interface than would otherwise be possible.34/// It does, however, know just enough to be able to provide a higher-level interface than would otherwise be possible.
@@ -196,3 +119,42 @@ impl<T: Transport> TransportV2Ext for T { · 84 unmodified lines
196 Ok(writer.into_read()?)119 Ok(writer.into_read()?)
197 }120 }
198}121}
122
123mod box_impl {
124 use crate::{
125 client::{self, Error, Identity, MessageKind, RequestWriter, SetServiceResponse, WriteMode},
126 Protocol, Service,
127 };
128 use std::ops::{Deref, DerefMut};
129
130 // Would be nice if the box implementation could auto-forward to all implemented traits.
131 impl<T: client::Transport + ?Sized> client::Transport for Box<T> {
132 fn handshake(&mut self, service: Service) -> Result<SetServiceResponse<'_>, Error> {
133 self.deref_mut().handshake(service)
134 }
135
136 fn set_identity(&mut self, identity: Identity) -> Result<(), Error> {
137 self.deref_mut().set_identity(identity)
138 }
139
140 fn request(&mut self, write_mode: WriteMode, on_into_read: MessageKind) -> Result<RequestWriter<'_>, Error> {
141 self.deref_mut().request(write_mode, on_into_read)
142 }
143
144 fn close(&mut self) -> Result<(), Error> {
145 self.deref_mut().close()
146 }
147
148 fn to_url(&self) -> String {
149 self.deref().to_url()
150 }
151
152 fn desired_protocol_version(&self) -> Protocol {
153 self.deref().desired_protocol_version()
154 }
155
156 fn is_stateful(&self) -> bool {
157 self.deref().is_stateful()
158 }
159 }
160}
git-transport/src/client/mod.rs+90−1
@@ -9,12 +9,101 @@ mod _blocking_api_exports { · 8 unmodified lines
9 pub use super::blocking_io::{9 pub use super::blocking_io::{
10 file, git,10 file, git,
11 request::{ExtendedBufRead, HandleProgress, RequestWriter},11 request::{ExtendedBufRead, HandleProgress, RequestWriter},
12 ssh, Error, Identity, MessageKind, SetServiceResponse, Transport, TransportV2Ext, WriteMode,12 ssh, SetServiceResponse, Transport, TransportV2Ext,
13 };13 };
14}14}
15#[cfg(feature = "blocking-client")]15#[cfg(feature = "blocking-client")]
16pub use _blocking_api_exports::*;16pub use _blocking_api_exports::*;
17 17
18mod error {
19 use crate::client::capabilities;
20 #[cfg(feature = "http-client-curl")]
21 use crate::client::http;
22 #[cfg(feature = "http-client-curl")]
23 type HttpError = http::Error;
24 #[cfg(not(feature = "http-client-curl"))]
25 type HttpError = std::convert::Infallible;
26
27 /// The error used in most methods of the [`client`][crate::client] module
28 #[derive(thiserror::Error, Debug)]
29 #[allow(missing_docs)]
30 pub enum Error {
31 #[error("An IO error occurred when talking to the server")]
32 Io {
33 #[from]
34 err: std::io::Error,
35 },
36 #[error("Capabilities could not be parsed")]
37 Capabilities {
38 #[from]
39 err: capabilities::Error,
40 },
41 #[error("A packet line could not be decoded")]
42 LineDecode {
43 #[from]
44 err: git_packetline::decode::Error,
45 },
46 #[error("A {0} line was expected, but there was none")]
47 ExpectedLine(&'static str),
48 #[error("Expected a data line, but got a delimiter")]
49 ExpectedDataLine,
50 #[error("The transport layer does not support authentication")]
51 AuthenticationUnsupported,
52 #[error("The transport layer refuses to use a given identity: {0}")]
53 AuthenticationRefused(&'static str),
54 #[error(transparent)]
55 Http(#[from] HttpError),
56 }
57}
58pub use error::Error;
59
60mod types {
61 /// Configure how the [`RequestWriter`][crate::client::RequestWriter] behaves when writing bytes.
62 #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
63 #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
64 pub enum WriteMode {
65 /// Each [write()][Write::write()] call writes the bytes verbatim as one or more packet lines.
66 Binary,
67 /// Each [write()][Write::write()] call assumes text in the input, assures a trailing newline and writes it as single packet line.
68 OneLfTerminatedLinePerWriteCall,
69 }
70
71 impl Default for WriteMode {
72 fn default() -> Self {
73 WriteMode::OneLfTerminatedLinePerWriteCall
74 }
75 }
76
77 /// The kind of packet line to write when transforming a [`RequestWriter`][crate::client::RequestWriter] into an
78 /// [`ExtendedBufRead`][crate::client::ExtendedBufRead].
79 #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
80 #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
81 pub enum MessageKind {
82 /// A `flush` packet.
83 Flush,
84 /// A V2 delimiter.
85 Delimiter,
86 /// The end of a response.
87 ResponseEnd,
88 /// The given text.
89 Text(&'static [u8]),
90 }
91
92 #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
93 #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
94 /// An identity for use when authenticating the transport layer.
95 pub enum Identity {
96 /// An account based identity
97 Account {
98 /// The user's name
99 username: String,
100 /// The user's password
101 password: String,
102 },
103 }
104}
105pub use types::{Identity, MessageKind, WriteMode};
106
18///107///
19pub mod capabilities;108pub mod capabilities;
20#[doc(inline)]109#[doc(inline)]