1- use async_trait:: async_trait;
2-
31use crate :: {
42 client:: { SetServiceResponse , Transport , TransportWithoutIO } ,
53 Protocol , Service ,
64} ;
5+ use async_trait:: async_trait;
76
8- pub struct NativeSsh ;
7+ mod client;
8+ mod error;
9+
10+ pub use error:: Error ;
11+
12+ pub struct NativeSsh {
13+ url : gix_url:: Url ,
14+ desired_version : Protocol ,
15+ trace : bool ,
16+
17+ identity : Option < gix_sec:: identity:: Account > ,
18+ client : Option < client:: Client > ,
19+ connection : Option < crate :: client:: git:: Connection < & ' static [ u8 ] , Vec < u8 > > > ,
20+ }
921
1022impl TransportWithoutIO for NativeSsh {
23+ fn set_identity ( & mut self , identity : gix_sec:: identity:: Account ) -> Result < ( ) , crate :: client:: Error > {
24+ self . identity = Some ( identity) ;
25+ Ok ( ( ) )
26+ }
27+
1128 fn request (
1229 & mut self ,
1330 write_mode : crate :: client:: WriteMode ,
@@ -18,18 +35,18 @@ impl TransportWithoutIO for NativeSsh {
1835 }
1936
2037 fn to_url ( & self ) -> std:: borrow:: Cow < ' _ , bstr:: BStr > {
21- todo ! ( )
38+ self . url . to_bstring ( ) . into ( )
2239 }
2340
2441 fn connection_persists_across_multiple_requests ( & self ) -> bool {
25- todo ! ( )
42+ true
2643 }
2744
2845 fn configure (
2946 & mut self ,
3047 config : & dyn std:: any:: Any ,
3148 ) -> Result < ( ) , Box < dyn std:: error:: Error + Send + Sync + ' static > > {
32- todo ! ( )
49+ Ok ( ( ) )
3350 }
3451}
3552
@@ -40,14 +57,59 @@ impl Transport for NativeSsh {
4057 service : Service ,
4158 extra_parameters : & ' a [ ( & ' a str , Option < & ' a str > ) ] ,
4259 ) -> Result < SetServiceResponse < ' _ > , crate :: client:: Error > {
43- todo ! ( )
60+ let host = self . url . host ( ) . expect ( "url has host" ) ;
61+ let port = self . url . port_or_default ( ) . expect ( "ssh has a default port" ) ;
62+
63+ let auth_mode = match self . identity . as_ref ( ) {
64+ Some ( crate :: client:: Account {
65+ username,
66+ password,
67+ oauth_refresh_token : _,
68+ } ) => client:: AuthMode :: UsernamePassword {
69+ username : username. clone ( ) ,
70+ password : password. clone ( ) ,
71+ } ,
72+ None => return Err ( crate :: client:: Error :: AuthenticationUnsupported ) ,
73+ } ;
74+
75+ let client = client:: Client :: connect ( host, port, auth_mode) . await ?;
76+
77+ let connection = crate :: client:: git:: Connection :: new (
78+ [ 0u8 ] . as_slice ( ) , // TODO
79+ vec ! [ ] , // TODO
80+ self . desired_version ,
81+ self . url . path . clone ( ) ,
82+ None :: < ( String , _ ) > ,
83+ crate :: client:: git:: ConnectMode :: Process ,
84+ self . trace ,
85+ ) ;
86+
87+ self . client = Some ( client) ;
88+ self . connection = Some ( connection) ;
89+
90+ self . connection
91+ . as_mut ( )
92+ . expect ( "connection to be there right after setting it" )
93+ . handshake ( service, extra_parameters)
94+ . await
4495 }
4596}
4697
98+ #[ allow( clippy:: unused_async) ]
4799pub async fn connect (
48100 url : gix_url:: Url ,
49101 desired_version : Protocol ,
50102 trace : bool ,
51- ) -> Result < NativeSsh , crate :: client:: Error > {
52- todo ! ( )
103+ ) -> Result < NativeSsh , crate :: client:: connect:: Error > {
104+ if url. scheme != gix_url:: Scheme :: Ssh {
105+ return Err ( crate :: client:: connect:: Error :: UnsupportedScheme ( url. scheme ) ) ;
106+ }
107+ Ok ( NativeSsh {
108+ url,
109+ desired_version,
110+ trace,
111+ identity : None ,
112+ client : None ,
113+ connection : None ,
114+ } )
53115}
0 commit comments