#![allow(clippy::print_stdout, clippy::print_stderr)]
mod bind;
mod keygen;
mod migrate;
mod name;
mod plan_io;
mod record;
mod refresh;
mod resolve;
mod rotate;
mod seed;
mod store_dir;
mod vouch;
mod watch;
use std::{
io::Write as _,
net::SocketAddr,
process::ExitCode,
time::{SystemTime, UNIX_EPOCH},
};
use clap::Parser;
use onomancy_hickory::provider::HickoryProvider;
#[derive(Debug, Parser)]
#[command(name = "onomancer", version, about)]
enum Command {
Bind(bind::Bind),
Keygen(keygen::Keygen),
Migrate(migrate::Migrate),
Name(name::NameWalk),
Record(record::Record),
Refresh(refresh::Refresh),
Resolve(resolve::Resolve),
Rotate(rotate::Rotate),
Vouch(vouch::Vouch),
Watch(watch::Watch),
}
fn main() -> ExitCode {
let outcome: Result<(), Box<dyn std::error::Error>> = match Command::parse() {
Command::Bind(command) => command.run().map_err(Into::into),
Command::Keygen(command) => command.run().map_err(Into::into),
Command::Migrate(command) => command.run().map_err(Into::into),
Command::Name(command) => command.run().map_err(Into::into),
Command::Record(command) => command.run().map_err(Into::into),
Command::Refresh(command) => command.run().map_err(Into::into),
Command::Resolve(command) => command.run().map_err(Into::into),
Command::Rotate(command) => command.run().map_err(Into::into),
Command::Vouch(command) => command.run().map_err(Into::into),
Command::Watch(command) => command.run().map_err(Into::into),
};
match outcome {
Ok(()) => ExitCode::SUCCESS,
Err(error) => {
eprintln!("error: {error}");
ExitCode::FAILURE
}
}
}
pub(crate) fn provider(resolver: Option<SocketAddr>) -> HickoryProvider {
resolver.map_or_else(HickoryProvider::system, HickoryProvider::new)
}
pub(crate) fn now_ms() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_or(0, |elapsed| {
u64::try_from(elapsed.as_millis()).unwrap_or(u64::MAX)
})
}
pub(crate) fn block_on<F: Future>(future: F) -> Result<F::Output, std::io::Error> {
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()?;
Ok(runtime.block_on(future))
}
pub(crate) fn say(line: &str) {
if let Err(failure) = writeln!(std::io::stdout(), "{line}")
&& failure.kind() == std::io::ErrorKind::BrokenPipe
{
std::process::exit(0);
}
}