use std::path::Path;
use anyhow::Result;
use formats::phone::PhoneField;
use transport::iroh::Endpoint;
use crate::commands::{contacts, get, list, send, threads};
use crate::progress::with_spinner;
pub(in crate::commands) fn canonical_number(value: &str) -> String {
PhoneField::new(value, None).display().to_owned()
}
pub(in crate::commands) async fn run_list(
cfg: &::config::Config,
spoke: Option<&Endpoint>,
device: Option<&str>,
mut opts: list::ListOpts,
db: &store::Store,
config_path: Option<&Path>,
) -> Result<String> {
opts.from = opts.from.map(|f| canonical_number(&f));
if is_opted_in(db, "sync_enabled").await {
with_spinner("listing", list::run_store(opts, db)).await
} else {
with_spinner("listing", list::run(cfg, spoke, device, opts, config_path)).await
}
}
pub(in crate::commands) async fn run_contacts(
cfg: &::config::Config,
spoke: Option<&Endpoint>,
device: Option<&str>,
mut opts: contacts::ContactsOpts,
db: &store::Store,
config_path: Option<&Path>,
) -> Result<String> {
if opts.sync {
let fut = contacts::run_sync(cfg, spoke, device, db, config_path);
return with_spinner("syncing contacts", fut).await;
}
opts.lookup = opts.lookup.map(|n| canonical_number(&n));
if is_opted_in(db, "contacts_synced").await {
with_spinner("contacts", contacts::run_store(&opts, db)).await
} else {
with_spinner("contacts", contacts::run(cfg, spoke, device, &opts, config_path)).await
}
}
pub(in crate::commands) async fn run_get(
cfg: &::config::Config,
spoke: Option<&Endpoint>,
device: Option<&str>,
handle: String,
mark_read: bool,
db: &store::Store,
config_path: Option<&Path>,
) -> Result<String> {
if is_opted_in(db, "sync_enabled").await {
with_spinner("fetching", get::run_store(handle, mark_read, db)).await
} else {
with_spinner("fetching", get::run(cfg, spoke, device, handle, mark_read, config_path)).await
}
}
pub(in crate::commands) async fn run_threads(
cfg: &::config::Config,
spoke: Option<&Endpoint>,
device: Option<&str>,
db: &store::Store,
config_path: Option<&Path>,
) -> Result<String> {
if is_opted_in(db, "sync_enabled").await {
with_spinner("threads", threads::run_store(db)).await
} else {
with_spinner("threads", threads::run(cfg, spoke, device, config_path)).await
}
}
pub(in crate::commands) async fn run_send(
cfg: &::config::Config,
spoke: Option<&Endpoint>,
device: Option<&str>,
number: String,
message: String,
db: &store::Store,
config_path: Option<&Path>,
) -> Result<String> {
let number = canonical_number(&number);
if is_opted_in(db, "sync_enabled").await {
let fut = send::run(cfg, spoke, device, number, message, db, config_path);
with_spinner("sending", fut).await
} else {
let fut = send::run_live(cfg, spoke, device, number, message, config_path);
with_spinner("sending", fut).await
}
}
async fn is_opted_in(store: &store::Store, key: &str) -> bool {
match store.get_meta(key).await {
Ok(v) => v.as_deref() == Some("true"),
Err(e) => {
tracing::warn!("failed to read {key} from store, falling back to phone: {e}");
false
}
}
}
#[cfg(test)]
mod tests;