use crate::options::agent::AgentOptions;
use bsky_sdk::{
agent::config::{Config, FileStore},
BskyAgent,
};
use camino::Utf8PathBuf;
use iri_string::types::UriAbsoluteString;
use keyring::Entry;
pub(crate) mod api;
pub(crate) mod flow;
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
#[error(transparent)]
pub(crate) enum Error {
BlueSky(#[from] bsky_sdk::Error),
Api(#[from] api::Error),
Flow(#[from] flow::Error),
#[error("missing authority")]
MissingAuthority,
#[error("missing password")]
MissingPassword,
Keyring(#[from] keyring::Error),
Json(#[from] serde_json::Error),
Yaml(#[from] serde_yml::Error),
Io(#[from] std::io::Error),
}
#[derive(Debug, Clone, clap::Parser)]
#[command(arg_required_else_help = true, about = "online operations")]
pub(crate) struct Command {
#[command(flatten)]
agent: AgentOptions,
#[command(subcommand)]
subcommand: Option<Subcommand>,
}
#[derive(Debug, Clone, clap::Subcommand)]
pub(crate) enum Subcommand {
#[command(subcommand)]
Api(api::FlatCommand),
#[command(subcommand)]
Flow(flow::Command),
}
impl Command {
pub(crate) async fn run(self) -> Result<Box<dyn crate::Output>, Error> {
let Self { agent, subcommand } = self;
let json = match subcommand {
None => String::from("{}"),
Some(command) => {
let output = match command {
Subcommand::Api(command) => {
let loader = FileStore::from(agent.config.file);
let config = Config::load(&loader).await?;
let agent = BskyAgent::builder().config(config).build().await?;
command.with(&agent).await?
}
Subcommand::Flow(command) => command.run(agent).await?,
};
serde_json::to_string_pretty(&output)?
}
};
println!("{json}");
Ok(Box::new(()))
}
}