1#[cfg(any(feature = "starttls-rust", feature = "starttls-native"))]
8use crate::tokio_xmpp::connect::{DnsConfig, StartTlsServerConnector};
9use core::str::FromStr;
10
11use crate::{
12 jid::{BareJid, Jid, ResourceRef},
13 parsers::{
14 disco::{DiscoInfoResult, Feature, Identity},
15 ns,
16 },
17 tokio_xmpp::{connect::ServerConnector, xmlstream::Timeouts, Client as TokioXmppClient},
18 Agent, ClientFeature, RoomNick,
19};
20
21#[derive(Debug)]
22pub enum ClientType {
23 Bot,
24 Pc,
25}
26
27impl Default for ClientType {
28 fn default() -> Self {
29 ClientType::Bot
30 }
31}
32
33impl ToString for ClientType {
34 fn to_string(&self) -> String {
35 String::from(match self {
36 ClientType::Bot => "bot",
37 ClientType::Pc => "pc",
38 })
39 }
40}
41
42pub struct ClientBuilder<'a, C: ServerConnector> {
43 jid: BareJid,
44 password: &'a str,
45 server_connector: C,
46 website: String,
47 default_nick: RoomNick,
48 lang: Vec<String>,
49 disco: (ClientType, String),
50 features: Vec<ClientFeature>,
51 resource: Option<String>,
52 timeouts: Timeouts,
53}
54
55#[cfg(any(feature = "starttls-rust", feature = "starttls-native"))]
56impl ClientBuilder<'_, StartTlsServerConnector> {
57 pub fn new<'a>(jid: BareJid, password: &'a str) -> ClientBuilder<'a, StartTlsServerConnector> {
58 Self::new_with_connector(
59 jid.clone(),
60 password,
61 StartTlsServerConnector(DnsConfig::srv_default_client(jid.domain())),
62 )
63 }
64}
65
66impl<C: ServerConnector> ClientBuilder<'_, C> {
67 pub fn new_with_connector<'a>(
68 jid: BareJid,
69 password: &'a str,
70 server_connector: C,
71 ) -> ClientBuilder<'a, C> {
72 ClientBuilder {
73 jid,
74 password,
75 server_connector,
76 website: String::from("https://gitlab.com/xmpp-rs/tokio-xmpp"),
77 default_nick: RoomNick::from_str("xmpp-rs").unwrap(),
78 lang: vec![String::from("en")],
79 disco: (ClientType::default(), String::from("tokio-xmpp")),
80 features: vec![],
81 resource: None,
82 timeouts: Timeouts::default(),
83 }
84 }
85
86 pub fn set_resource(mut self, resource: &str) -> Self {
88 self.resource = Some(resource.to_string());
89 self
90 }
91
92 pub fn set_client(mut self, type_: ClientType, name: &str) -> Self {
93 self.disco = (type_, String::from(name));
94 self
95 }
96
97 pub fn set_website(mut self, url: &str) -> Self {
98 self.website = String::from(url);
99 self
100 }
101
102 pub fn set_default_nick(mut self, nick: impl AsRef<ResourceRef>) -> Self {
103 self.default_nick = RoomNick::from_resource_ref(nick.as_ref());
104 self
105 }
106
107 pub fn set_lang(mut self, lang: Vec<String>) -> Self {
108 self.lang = lang;
109 self
110 }
111
112 pub fn set_timeouts(mut self, timeouts: Timeouts) -> Self {
117 self.timeouts = timeouts;
118 self
119 }
120
121 pub fn enable_feature(mut self, feature: ClientFeature) -> Self {
122 self.features.push(feature);
123 self
124 }
125
126 fn make_disco(&self) -> DiscoInfoResult {
127 let identities = vec![Identity::new(
128 "client",
129 self.disco.0.to_string(),
130 "en",
131 self.disco.1.to_string(),
132 )];
133 let mut features = vec![Feature::new(ns::DISCO_INFO)];
134 #[cfg(feature = "avatars")]
135 {
136 if self.features.contains(&ClientFeature::Avatars) {
137 features.push(Feature::new(format!("{}+notify", ns::AVATAR_METADATA)));
138 }
139 }
140 if self.features.contains(&ClientFeature::JoinRooms) {
141 features.push(Feature::new(format!("{}+notify", ns::BOOKMARKS2)));
142 }
143 DiscoInfoResult {
144 node: None,
145 identities,
146 features,
147 extensions: vec![],
148 }
149 }
150
151 pub fn build(self) -> Agent {
152 let jid: Jid = if let Some(resource) = &self.resource {
153 self.jid.with_resource_str(resource).unwrap().into()
154 } else {
155 self.jid.clone().into()
156 };
157
158 let client = TokioXmppClient::new_with_connector(
159 jid,
160 self.password,
161 self.server_connector.clone(),
162 self.timeouts,
163 );
164 self.build_impl(client)
165 }
166
167 pub(crate) fn build_impl(self, client: TokioXmppClient) -> Agent {
169 let disco = self.make_disco();
170 let node = self.website;
171
172 Agent::new(client, self.default_nick, self.lang, disco, node)
173 }
174}