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