etwin_cli 0.12.5

Command Line Interface for Eternaltwin
Documentation
use clap::Parser;
use dialoguer::{theme::ColorfulTheme, Input, Password, Select};
use etwin_core::clock::SystemClock;
use etwin_core::email::EmailAddress;
use etwin_core::oauth::RfcOauthAccessTokenKey;
use etwin_core::twinoid::{TwinoidApiAuth, TwinoidClient, TwinoidCredentials, TwinoidPassword, TwinoidSession};
use etwin_core::types::AnyError;
use etwin_twinoid_client::http::HttpTwinoidClient;
use std::str::FromStr;

/// Arguments to the `twinoid` task.
#[derive(Debug, Parser)]
pub struct Args {}

pub async fn run(_args: &Args) -> Result<(), AnyError> {
  let clock = SystemClock;
  let twinoid_client = HttpTwinoidClient::new(clock)?;

  let scenario = vec!["api", "website"];
  let scenario = Select::with_theme(&ColorfulTheme::default())
    .with_prompt("Scenario?")
    .items(&scenario)
    .default(0)
    .interact_opt()?;

  match scenario {
    Some(0) => {
      let token: String = Input::with_theme(&ColorfulTheme::default())
        .with_prompt("Access token?")
        .interact_text()?;

      let token: RfcOauthAccessTokenKey = token.parse()?;

      let auth = TwinoidApiAuth::Token(token);

      eprintln!("Fetching `me`");
      let me = twinoid_client.get_me_short(auth).await?;
      eprintln!("Fetched `me`:");
      eprintln!("{:#?}", &me);
    }
    Some(1) => {
      let session = auth_tid_creds(&twinoid_client).await?;
      eprintln!("Acquired Twinoid session");
      eprintln!("{:#?}", session);
    }
    _ => panic!("Failed to select scenario"),
  };

  Ok(())
}

pub async fn auth_tid_creds(tid_client: &HttpTwinoidClient<SystemClock>) -> Result<TwinoidSession, AnyError> {
  let email: String = Input::with_theme(&ColorfulTheme::default())
    .with_prompt("Email?")
    .interact_text()?;

  let email = EmailAddress::from_str(email.as_str())?;

  let password: String = Password::with_theme(&ColorfulTheme::default())
    .with_prompt("Password?")
    .interact()?;

  let password = TwinoidPassword::new(password.to_string());

  let credentials = TwinoidCredentials { email, password };

  eprintln!("Starting authentication");
  let tid_session = tid_client.create_session(&credentials).await?;
  Ok(tid_session)
}