#![warn(missing_docs)]
#![deny(unsafe_code)]
pub mod chat;
pub mod diagnostics;
pub mod network;
pub mod testing;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tokio::sync::RwLock;
#[derive(Clone)]
pub struct CommuniasApp {
pub chat_service: Arc<chat::ChatService>,
pub diagnostics: Arc<diagnostics::DiagnosticsEngine>,
#[cfg(feature = "test-harness")]
pub test_harness: Arc<testing::TestHarness>,
pub network: Arc<network::NetworkIntegration>,
pub state: Arc<RwLock<AppState>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppState {
pub identity: Identity,
pub current_tab: Tab,
pub connected: bool,
pub bootstrap_node: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Identity {
pub four_word_address: String,
pub public_key: Vec<u8>,
pub display_name: Option<String>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub enum Tab {
Overview,
Messages,
Network,
Storage,
Advanced,
}
impl std::fmt::Debug for CommuniasApp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CommuniasApp")
.field("chat_service", &"Arc<ChatService>")
.field("diagnostics", &"Arc<DiagnosticsEngine>")
.field("network", &"Arc<NetworkIntegration>")
.field("state", &"Arc<RwLock<AppState>>")
.finish()
}
}
impl CommuniasApp {
pub async fn new(bootstrap_node: String) -> Result<Self> {
let network = Arc::new(network::NetworkIntegration::new(bootstrap_node.clone()).await?);
let chat_service = Arc::new(chat::ChatService::new(network.clone()).await?);
let diagnostics = Arc::new(diagnostics::DiagnosticsEngine::new(network.clone()));
let identity = network.get_or_create_identity().await?;
let state = Arc::new(RwLock::new(AppState {
identity,
current_tab: Tab::Overview,
connected: false,
bootstrap_node,
}));
Ok(Self {
chat_service,
diagnostics,
#[cfg(feature = "test-harness")]
test_harness: Arc::new(testing::TestHarness::new()),
network,
state,
})
}
pub async fn connect(&self) -> Result<()> {
self.network.connect_to_bootstrap().await?;
let mut state = self.state.write().await;
state.connected = true;
self.diagnostics.start_collection();
Ok(())
}
pub async fn get_network_health(&self) -> diagnostics::NetworkHealth {
self.diagnostics.get_network_health().await
}
}