use apperror::AppError;
use rules::Rule;
use std::{env, process::ExitCode, thread::sleep, time::Duration};
use tokio::runtime::Runtime;
pub mod apperror;
pub mod builder;
mod channel;
mod channel_handler;
mod command_channel;
mod model;
mod rpc_helper;
pub mod rules;
pub mod session;
mod tcp_channel;
async fn run() -> Result<(), AppError> {
let token = env::var("TOKEN").map_err(|_| AppError::new("failed to read TOKEN from env"))?;
let client_name = env::var("CLIENT_NAME").ok();
let client_id = env::var("CLIENT_ID").ok();
let rule = if let Ok(rule) = env::var("RULE") {
Rule::parse(&rule)?
} else {
Rule::unrestricted()
};
log::info!("using rule:\n{:}", rule);
loop {
let builder = crate::builder::Builder::new(&token)
.with_client_name_opt(&client_name)
.with_client_id_opt(&client_id)
.with_rule(rule.clone())
.with_tls(true);
#[cfg(feature = "no-tls")]
let builder = builder.with_tls(false);
match builder.connect().await {
Ok(_) => continue,
Err(e) => {
log::error!("error: {:?}", e);
sleep(Duration::from_secs(5));
}
}
}
}
pub fn tnnl_main() -> ExitCode {
#[cfg(feature = "log-colog")]
colog::init();
#[cfg(feature = "init-rustls")]
{
if Result::is_err(&rustls::crypto::aws_lc_rs::default_provider().install_default()) {
log::error!(
"failed to install crypto provider; if there is one already installed disable the init-rustls feature"
);
return ExitCode::FAILURE;
}
}
let Ok(rt) = Runtime::new() else {
log::error!("failed to start runtime");
return ExitCode::FAILURE;
};
rt.block_on(async {
match run().await {
Ok(_) => ExitCode::SUCCESS,
Err(e) => {
log::error!("{:}", e);
ExitCode::FAILURE
}
}
})
}
#[unsafe(export_name = "tnnl_main")]
pub extern "C" fn tnnl_main_extern() -> u8 {
let exit_code = tnnl_main();
match exit_code {
ExitCode::SUCCESS => 0,
_ => 1,
}
}