Создает и устанавливает соединение с сервером CloudPub. Этот метод: 1. Проверяет конфигурацию 2. Инициализирует логирование 3. Загружает или создает файл конфигурации 4. Аутентифицируется на сервере (если предоставлены учетные данные) 5. Устанавливает соединение 6. Ожидает готовности соединения # Возвращает Возвращает экземпляр `Connection` при успехе, или ошибку, если: - Неверная конфигурация
(self)
| 435 | /// - Неудачное соединение с сервером |
| 436 | /// - Таймаут ожидания соединения |
| 437 | pub async fn build(self) -> Result<Connection> { |
| 438 | // Проверяем аутентификацию, если она предоставлена |
| 439 | if self.email.is_some() && self.password.is_none() { |
| 440 | bail!("Password is required when email is provided"); |
| 441 | } |
| 442 | if self.password.is_some() && self.email.is_none() { |
| 443 | bail!("Email is required when password is provided"); |
| 444 | } |
| 445 | |
| 446 | // Увеличиваем лимит `nofile` на Linux и Mac |
| 447 | if let Err(err) = fdlimit::raise_fd_limit() { |
| 448 | warn!("Failed to raise file descriptor limit: {}", err); |
| 449 | } |
| 450 | |
| 451 | // Создаем директорию для логов |
| 452 | let log_dir = cache_dir().context("Can't get cache dir")?.join("cloudpub"); |
| 453 | std::fs::create_dir_all(&log_dir).context("Can't create log dir")?; |
| 454 | |
| 455 | let log_file = log_dir.join("client.log"); |
| 456 | |
| 457 | // Инициализируем логирование |
| 458 | let _guard = init_log( |
| 459 | &self.log_level, |
| 460 | &log_file, |
| 461 | self.verbose, |
| 462 | 10 * 1024 * 1024, |
| 463 | 2, |
| 464 | ) |
| 465 | .context("Failed to initialize logging")?; |
| 466 | |
| 467 | // Загружаем конфигурацию |
| 468 | let mut config = if let Some(ref path) = self.config_path { |
| 469 | ClientConfig::from_file(path, false)? |
| 470 | } else { |
| 471 | ClientConfig::load("client.toml", true, false)? |
| 472 | }; |
| 473 | |
| 474 | // Обрабатываем аутентификацию по токену |
| 475 | if let Some(token_value) = self.token { |
| 476 | config.token = Some(MaskedString(token_value)); |
| 477 | } |
| 478 | |
| 479 | let config = Arc::new(RwLock::new(config)); |
| 480 | |
| 481 | // Настраиваем каналы |
| 482 | let (command_tx, command_rx) = mpsc::channel(1024); |
| 483 | let (result_tx, result_rx) = mpsc::channel(1024); |
| 484 | |
| 485 | // Определяем опции на основе аутентификации |
| 486 | let opts = if let Some(email_value) = self.email { |
| 487 | if let Some(password_value) = self.password { |
| 488 | ClientOpts { |
| 489 | credentials: Some((email_value, password_value)), |
| 490 | ..Default::default() |
| 491 | } |
| 492 | } else { |
| 493 | // Это не должно произойти из-за проверки выше |
| 494 | ClientOpts::default() |
no test coverage detected