skytool 0.1.0-pre.2

an experimental API client for BlueSky / ATProto
Documentation
use bsky_sdk::{
  agent::config::{Config, FileStore},
  BskyAgent,
};

use crate::options::agent::AgentOptions;

use super::api::{self, com::atproto::server::create_session};

#[derive(Debug, thiserror::Error, miette::Diagnostic)]
#[error(transparent)]
pub(crate) enum Error {
  Api(super::api::Error),
  BlueSky(#[from] bsky_sdk::Error),
}

impl<T> From<T> for Error
where
  api::Error: From<T>,
{
  fn from(error: T) -> Self {
    api::Error::from(error).into()
  }
}

#[derive(Debug, Clone, clap::Subcommand)]
pub(crate) enum Command {
  Login(Login),
}

impl Command {
  pub(crate) async fn run(self, agent: AgentOptions) -> Result<Box<dyn crate::Output>, Error> {
    match self {
      Self::Login(this) => this.run(agent).await,
    }
  }
}

#[derive(Debug, Clone, clap::Parser)]
#[command(about = "login flow")]
pub(crate) struct Login {
  #[command(flatten)]
  create_session: create_session::Command,
}

impl Login {
  pub(crate) async fn run(self, agent: AgentOptions) -> Result<Box<dyn crate::Output>, Error> {
    let Self {
      create_session: create_session::Command {
        identifier, password, ..
      },
    } = self;

    let saver = FileStore::new(agent.config.file);
    let agent = BskyAgent::builder().build().await?;
    agent.login(identifier, password).await?;
    let config = agent.to_config().await;
    config.save(&saver).await?;

    Ok(Box::new(config))
  }
}