// Avoid spurious warnings with --no-default-features, which isn't expected to // work anyway #![cfg_attr(not(any(feature = "sqlite", feature = "rocksdb")), allow(unused))] use std::{process::ExitCode, sync::RwLock}; use clap::Parser; use tracing::error; mod api; mod cli; mod config; mod database; mod error; mod observability; mod service; mod utils; pub(crate) use api::ruma_wrapper::{Ar, Ra}; pub(crate) use config::Config; pub(crate) use service::{pdu::PduEvent, Services}; #[cfg(all(not(target_env = "msvc"), feature = "jemalloc"))] use tikv_jemallocator::Jemalloc; pub(crate) use utils::error::{Error, Result}; #[cfg(all(not(target_env = "msvc"), feature = "jemalloc"))] #[global_allocator] static GLOBAL: Jemalloc = Jemalloc; pub(crate) static SERVICES: RwLock> = RwLock::new(None); /// Convenient access to the global [`Services`] instance pub(crate) fn services() -> &'static Services { SERVICES .read() .unwrap() .expect("SERVICES should be initialized when this is called") } /// Returns the current version of the crate with extra info if supplied /// /// Set the environment variable `GRAPEVINE_VERSION_EXTRA` to any UTF-8 string /// to include it in parenthesis after the SemVer version. A common value are /// git commit hashes. fn version() -> String { let cargo_pkg_version = env!("CARGO_PKG_VERSION"); match option_env!("GRAPEVINE_VERSION_EXTRA") { Some(x) => format!("{cargo_pkg_version} ({x})"), None => cargo_pkg_version.to_owned(), } } #[tokio::main] async fn main() -> ExitCode { let args = cli::Args::parse(); let Err(e) = args.run().await else { return ExitCode::SUCCESS; }; eprintln!( "Error: {}", error::DisplayWithSources { error: &e, infix: "\n Caused by: " } ); ExitCode::FAILURE }