systemprompt_cli/commands/cloud/tenant/
select.rs1use anyhow::{anyhow, bail, Result};
2use dialoguer::theme::ColorfulTheme;
3use dialoguer::Select;
4use systemprompt_cloud::{
5 get_cloud_paths, CloudCredentials, CloudPath, CredentialsBootstrap, StoredTenant, TenantType,
6};
7use systemprompt_models::profile_bootstrap::ProfileBootstrap;
8
9pub fn get_credentials() -> Result<CloudCredentials> {
10 if CredentialsBootstrap::is_initialized() {
11 return CredentialsBootstrap::require()
12 .map_err(|e| {
13 anyhow!(
14 "Credentials required. Run 'systemprompt cloud login': {}",
15 e
16 )
17 })?
18 .clone()
19 .pipe(Ok);
20 }
21
22 let cloud_paths = get_cloud_paths()?;
23 let creds_path = cloud_paths.resolve(CloudPath::Credentials);
24
25 if creds_path.exists() {
26 CloudCredentials::load_from_path(&creds_path)
27 } else {
28 bail!("Not logged in. Run 'systemprompt cloud login' first.")
29 }
30}
31
32pub fn select_tenant(tenants: &[StoredTenant]) -> Result<&StoredTenant> {
33 let options: Vec<String> = tenants
34 .iter()
35 .map(|t| {
36 let type_str = match t.tenant_type {
37 TenantType::Local => "local",
38 TenantType::Cloud => "cloud",
39 };
40 format!("{} ({})", t.name, type_str)
41 })
42 .collect();
43
44 let selection = Select::with_theme(&ColorfulTheme::default())
45 .with_prompt("Select tenant")
46 .items(&options)
47 .default(0)
48 .interact()?;
49
50 Ok(&tenants[selection])
51}
52
53pub fn resolve_tenant_id(tenant_id: Option<String>) -> Result<String> {
54 if let Some(id) = tenant_id {
55 return Ok(id);
56 }
57
58 ProfileBootstrap::get()
59 .ok()
60 .and_then(|p| p.cloud.as_ref()?.tenant_id.clone())
61 .ok_or_else(|| {
62 anyhow!("No tenant specified. Use --tenant or configure a tenant in your profile.")
63 })
64}
65
66trait Pipe: Sized {
67 fn pipe<F, R>(self, f: F) -> R
68 where
69 F: FnOnce(Self) -> R,
70 {
71 f(self)
72 }
73}
74
75impl<T> Pipe for T {}