1use crate::client::WinrmClient;
7use crate::config::{WinrmConfig, WinrmCredentials};
8use crate::error::WinrmError;
9
10pub struct NeedsCredentials;
12pub struct Ready;
14
15pub struct WinrmClientBuilder<S = NeedsCredentials> {
29 config: WinrmConfig,
30 credentials: Option<WinrmCredentials>,
31 _state: std::marker::PhantomData<S>,
32}
33
34impl WinrmClientBuilder<NeedsCredentials> {
35 pub fn new(config: WinrmConfig) -> Self {
37 Self {
38 config,
39 credentials: None,
40 _state: std::marker::PhantomData,
41 }
42 }
43
44 pub fn credentials(self, creds: WinrmCredentials) -> WinrmClientBuilder<Ready> {
46 WinrmClientBuilder {
47 config: self.config,
48 credentials: Some(creds),
49 _state: std::marker::PhantomData,
50 }
51 }
52}
53
54impl WinrmClientBuilder<Ready> {
55 pub fn build(self) -> Result<WinrmClient, WinrmError> {
60 WinrmClient::new(
63 self.config,
64 self.credentials
65 .expect("typestate guarantees credentials are set"),
66 )
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn builder_creates_client() {
76 let client = WinrmClientBuilder::new(WinrmConfig::default())
77 .credentials(WinrmCredentials::new("admin", "pass", ""))
78 .build()
79 .unwrap();
80 assert_eq!(client.endpoint("test-host"), "http://test-host:5985/wsman");
82 }
83
84 #[test]
85 fn builder_preserves_custom_config() {
86 let config = WinrmConfig {
87 port: 5986,
88 use_tls: true,
89 max_envelope_size: 512_000,
90 ..Default::default()
91 };
92 let client = WinrmClientBuilder::new(config)
93 .credentials(WinrmCredentials::new("user", "pw", "DOM"))
94 .build()
95 .unwrap();
96 assert_eq!(client.endpoint("srv"), "https://srv:5986/wsman");
97 assert_eq!(client.config().max_envelope_size, 512_000);
98 }
99
100 #[test]
101 fn builder_via_client_static_method() {
102 let client = WinrmClient::builder(WinrmConfig::default())
103 .credentials(WinrmCredentials::new("admin", "pass", ""))
104 .build()
105 .unwrap();
106 assert_eq!(client.endpoint("host"), "http://host:5985/wsman");
107 }
108}