|
2 | 2 | mod error { |
3 | 3 | use crate::handshake::refs::parse; |
4 | 4 |
|
5 | | - /// The error returned by [`ls_refs()`][crate::ls_refs()]. |
| 5 | + /// The error returned by invoking a [`super::function::LsRefsCommand`]. |
6 | 6 | #[derive(Debug, thiserror::Error)] |
7 | 7 | #[allow(missing_docs)] |
8 | 8 | pub enum Error { |
@@ -48,51 +48,76 @@ pub(crate) mod function { |
48 | 48 | Command, |
49 | 49 | }; |
50 | 50 |
|
51 | | - /// Invoke a ls-refs V2 command on `transport`, which requires a prior handshake that yielded |
52 | | - /// server `capabilities`. `prepare_ls_refs(capabilities)` can be used to alter the _ls-refs_. |
53 | | - /// `arguments` are extra arguments to send to the server. |
54 | | - /// `progress` is used to provide feedback. |
55 | | - /// The `agent` information will be added to the features sent to the server. |
56 | | - /// If `trace` is `true`, all packetlines received or sent will be passed to the facilities of the `gix-trace` crate. |
57 | | - #[maybe_async] |
58 | | - pub async fn ls_refs( |
59 | | - mut transport: impl Transport, |
60 | | - capabilities: &Capabilities, |
61 | | - extra_args: Vec<BString>, |
62 | | - progress: &mut impl Progress, |
63 | | - trace: bool, |
64 | | - agent: (&'static str, Option<Cow<'static, str>>), |
65 | | - ) -> Result<Vec<Ref>, Error> { |
66 | | - let _span = gix_features::trace::detail!("gix_protocol::ls_refs()", capabilities = ?capabilities); |
67 | | - let ls_refs = Command::LsRefs; |
68 | | - let mut ls_features = ls_refs.default_features(gix_transport::Protocol::V2, capabilities); |
69 | | - ls_features.push(agent); |
70 | | - let mut ls_args = ls_refs.initial_v2_arguments(&ls_features); |
71 | | - if capabilities |
72 | | - .capability("ls-refs") |
73 | | - .and_then(|cap| cap.supports("unborn")) |
74 | | - .unwrap_or_default() |
75 | | - { |
76 | | - ls_args.push("unborn".into()); |
| 51 | + /// A command to list references from a remote Git repository. |
| 52 | + pub struct LsRefsCommand<'a> { |
| 53 | + capabilities: &'a Capabilities, |
| 54 | + features: Vec<(&'static str, Option<Cow<'static, str>>)>, |
| 55 | + arguments: Vec<BString>, |
| 56 | + } |
| 57 | + |
| 58 | + impl<'a> LsRefsCommand<'a> { |
| 59 | + /// Build a command to list refs from the given server `capabilities`, |
| 60 | + /// using `agent` information to identify ourselves. |
| 61 | + pub fn new(capabilities: &'a Capabilities, agent: (&'static str, Option<Cow<'static, str>>)) -> Self { |
| 62 | + let _span = |
| 63 | + gix_features::trace::detail!("gix_protocol::LsRefsCommand::new()", capabilities = ?capabilities); |
| 64 | + let ls_refs = Command::LsRefs; |
| 65 | + let mut features = ls_refs.default_features(gix_transport::Protocol::V2, capabilities); |
| 66 | + features.push(agent); |
| 67 | + let mut arguments = ls_refs.initial_v2_arguments(&features); |
| 68 | + if capabilities |
| 69 | + .capability("ls-refs") |
| 70 | + .and_then(|cap| cap.supports("unborn")) |
| 71 | + .unwrap_or_default() |
| 72 | + { |
| 73 | + arguments.push("unborn".into()); |
| 74 | + } |
| 75 | + |
| 76 | + Self { |
| 77 | + capabilities, |
| 78 | + features, |
| 79 | + arguments, |
| 80 | + } |
77 | 81 | } |
78 | 82 |
|
79 | | - ls_args.extend(extra_args); |
80 | | - ls_refs.validate_argument_prefixes(gix_transport::Protocol::V2, capabilities, &ls_args, &ls_features)?; |
| 83 | + /// Invoke a ls-refs V2 command on `transport`. |
| 84 | + /// |
| 85 | + /// `progress` is used to provide feedback. |
| 86 | + /// If `trace` is `true`, all packetlines received or sent will be passed to the facilities of the `gix-trace` crate. |
| 87 | + #[maybe_async] |
| 88 | + pub async fn invoke( |
| 89 | + self, |
| 90 | + mut transport: impl Transport, |
| 91 | + progress: &mut impl Progress, |
| 92 | + trace: bool, |
| 93 | + ) -> Result<Vec<Ref>, Error> { |
| 94 | + Command::LsRefs.validate_argument_prefixes( |
| 95 | + gix_transport::Protocol::V2, |
| 96 | + self.capabilities, |
| 97 | + &self.arguments, |
| 98 | + &self.features, |
| 99 | + )?; |
| 100 | + |
| 101 | + progress.step(); |
| 102 | + progress.set_name("list refs".into()); |
| 103 | + let mut remote_refs = transport |
| 104 | + .invoke( |
| 105 | + Command::LsRefs.as_str(), |
| 106 | + self.features.into_iter(), |
| 107 | + if self.arguments.is_empty() { |
| 108 | + None |
| 109 | + } else { |
| 110 | + Some(self.arguments.into_iter()) |
| 111 | + }, |
| 112 | + trace, |
| 113 | + ) |
| 114 | + .await?; |
| 115 | + Ok(from_v2_refs(&mut remote_refs).await?) |
| 116 | + } |
81 | 117 |
|
82 | | - progress.step(); |
83 | | - progress.set_name("list refs".into()); |
84 | | - let mut remote_refs = transport |
85 | | - .invoke( |
86 | | - ls_refs.as_str(), |
87 | | - ls_features.into_iter(), |
88 | | - if ls_args.is_empty() { |
89 | | - None |
90 | | - } else { |
91 | | - Some(ls_args.into_iter()) |
92 | | - }, |
93 | | - trace, |
94 | | - ) |
95 | | - .await?; |
96 | | - Ok(from_v2_refs(&mut remote_refs).await?) |
| 118 | + /// The arguments that will be sent to the server as part of the ls-refs command. |
| 119 | + pub fn arguments(&mut self) -> &mut Vec<BString> { |
| 120 | + &mut self.arguments |
| 121 | + } |
97 | 122 | } |
98 | 123 | } |
0 commit comments