| @@ -10,49 +10,15 @@ pub(crate) mod request; · 9 unmodified lines |
| 10 | /// | 10 | /// |
| 11 | pub mod ssh; | 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 | use bstr::BString; | 17 | use bstr::BString; |
| 15 | use std::{io, io::Write}; | 18 | use std::{io, io::Write}; |
| 16 | | 19 | |
| 17 | use crate::client::{capabilities, Capabilities}; | | |
| 18 | use request::{ExtendedBufRead, RequestWriter}; | 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 | /// The response of the [`handshake()`][Transport::handshake()] method. | 22 | /// The response of the [`handshake()`][Transport::handshake()] method. |
| 57 | pub struct SetServiceResponse<'a> { | 23 | pub struct SetServiceResponse<'a> { |
| 58 | /// The protocol the service can provide. May be different from the requested one | 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 | 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))] | | |
| 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 | /// 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 | |
| | 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 | } |