use std::sync::Arc; use anyhow::bail; use api::{Api, ApiBuilder}; use comm::{CommHandle, Peer}; use config::Config; use i2p::net::I2pSocketAddr; use serde::{Deserialize, Serialize}; use state::{ types::{MessageId, PeerId}, ApiState, CommState, State, }; pub mod api; pub mod comm; pub mod config; pub mod state; #[derive(Clone, Debug, Deserialize, Serialize)] pub struct MessageRelations { pub parents: Vec, } pub struct Ubisync { comm_handle: Arc, state_handle: Arc, api: Arc, } impl Ubisync { pub async fn new(config: &Config) -> anyhow::Result { let state = State::new().await?; let comm_handle = Arc::new(CommHandle::new(CommState::new(state.clone()), config)?); state.set_comm_handle(comm_handle.clone()); let api = Arc::new( ApiBuilder::from(config.api_config.clone()) .build(ApiState::new(state.clone(), &config.jwt_secret)) .await, ); comm_handle.run().await; Ok(Ubisync { comm_handle: comm_handle, state_handle: state, api: api, }) } pub fn api(&self) -> Arc { self.api.clone() } pub fn add_peer(&self, p: impl TryInto) -> anyhow::Result<()> { match p.try_into() { Ok(peer) => self.state_handle.set_peer(&peer), Err(e) => bail!(e), } } pub fn add_peer_from_id(&self, id: PeerId) -> anyhow::Result<()> { // TODO: resolve peer's name before setting self.state_handle.set_peer(&Peer::new(id, "".to_string())) } pub fn get_peers(&self) -> Vec { self.state_handle.get_peers().unwrap_or(vec![]) } pub fn get_destination(&self) -> anyhow::Result { self.comm_handle.i2p_address() } } #[cfg(test)] mod tests { #[test] #[ignore] fn full_system_test1() { // Do a test requiring a specific system state (including homeserver state or such) // Disabled by default, since files need to be set up explicitly for this test todo!() } }