Unified · Split
| @@ -33,45 +33,6 @@ quick_error! { · 32 unmodified lines | ||
| 33 | 33 | } |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | −mod 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 | 36 | /// A general purpose connector connecting to a repository identified by the given `url`. |
| 76 | 37 | /// |
| 77 | 38 | /// This includes connections to |
| @@ -10,49 +10,15 @@ pub(crate) mod request; · 9 unmodified lines | ||
| 10 | 10 | /// |
| 11 | 11 | pub mod ssh; |
| 12 | 12 | |
| 13 | −use crate::{Protocol, Service}; | |
| 13 | +use crate::{ | |
| 14 | + client::{capabilities, Capabilities, Error, Identity, MessageKind, WriteMode}, | |
| 15 | + Protocol, Service, | |
| 16 | +}; | |
| 14 | 17 | use bstr::BString; |
| 15 | 18 | use std::{io, io::Write}; |
| 16 | 19 | |
| 17 | −use crate::client::{capabilities, Capabilities}; | |
| 18 | 20 | use request::{ExtendedBufRead, RequestWriter}; |
| 19 | 21 | |
| 20 | −#[cfg(feature = "http-client-curl")] | |
| 21 | −type HttpError = http::Error; | |
| 22 | −#[cfg(not(feature = "http-client-curl"))] | |
| 23 | −type 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)] | |
| 28 | −pub 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 | 22 | /// The response of the [`handshake()`][Transport::handshake()] method. |
| 57 | 23 | pub struct SetServiceResponse<'a> { |
| 58 | 24 | /// 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 | 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))] | |
| 69 | −pub 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 | − | |
| 76 | −impl 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))] | |
| 85 | −pub 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. | |
| 99 | −pub 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 | 32 | /// All methods provided here must be called in the correct order according to the [communication protocol][Protocol] |
| 110 | 33 | /// used to connect to them. |
| 111 | 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 | 119 | Ok(writer.into_read()?) |
| 197 | 120 | } |
| 198 | 121 | } |
| 122 | + | |
| 123 | +mod 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 | +} | |
| @@ -9,12 +9,101 @@ mod _blocking_api_exports { · 8 unmodified lines | ||
| 9 | 9 | pub use super::blocking_io::{ |
| 10 | 10 | file, git, |
| 11 | 11 | request::{ExtendedBufRead, HandleProgress, RequestWriter}, |
| 12 | − ssh, Error, Identity, MessageKind, SetServiceResponse, Transport, TransportV2Ext, WriteMode, | |
| 12 | + ssh, SetServiceResponse, Transport, TransportV2Ext, | |
| 13 | 13 | }; |
| 14 | 14 | } |
| 15 | 15 | #[cfg(feature = "blocking-client")] |
| 16 | 16 | pub use _blocking_api_exports::*; |
| 17 | 17 | |
| 18 | +mod 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 | +} | |
| 58 | +pub use error::Error; | |
| 59 | + | |
| 60 | +mod 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 | +} | |
| 105 | +pub use types::{Identity, MessageKind, WriteMode}; | |
| 106 | + | |
| 18 | 107 | /// |
| 19 | 108 | pub mod capabilities; |
| 20 | 109 | #[doc(inline)] |