Skip to main content

sharepoint_cli/commands/
drives.rs

1//! `sharepoint drives list <site-ref>`
2
3use crate::auth::AuthContext;
4use crate::cli::{DrivesCmd, Runtime};
5use crate::error::{CliError, Result};
6use crate::graph::{GraphClient, drives, sites};
7use crate::reference::SiteRef;
8
9pub async fn run(rt: &Runtime, cmd: DrivesCmd) -> Result<()> {
10    match cmd {
11        DrivesCmd::List { site, limit, all } => list(rt, &site, limit, all).await,
12    }
13}
14
15async fn list(rt: &Runtime, site_input: &str, limit: usize, all: bool) -> Result<()> {
16    let auth = AuthContext::new(rt.cfg.clone(), rt.cache_path.clone());
17    let graph = GraphClient::new(auth);
18
19    // The site argument can be a URL, an alias name, "default", or spo://Site.
20    let site_ref = if site_input == "default" {
21        SiteRef::Default
22    } else if site_input.starts_with("http://") || site_input.starts_with("https://") {
23        SiteRef::Url(site_input.to_string())
24    } else if let Some(rest) = site_input.strip_prefix("spo://") {
25        // Accept bare spo://SiteName (and spo://SiteName/... with trailing segments ignored).
26        let name = rest
27            .split('/')
28            .next()
29            .filter(|s| !s.is_empty())
30            .ok_or_else(|| {
31                CliError::Input(
32                    "spo:// URI is missing a site name (expected spo://SiteName)".into(),
33                )
34            })?;
35        SiteRef::Name(name.to_string())
36    } else {
37        SiteRef::Name(site_input.to_string())
38    };
39
40    let site = sites::resolve(
41        &graph,
42        &site_ref,
43        &rt.cfg.site_aliases,
44        rt.cfg.default_site.as_deref(),
45    )
46    .await?;
47    let mut all_drives = drives::list_drives(&graph, &site.id).await?;
48    let total = all_drives.len();
49    if !all && all_drives.len() > limit {
50        all_drives.truncate(limit);
51    }
52
53    if rt.out.json {
54        let items: Vec<_> = all_drives
55            .iter()
56            .map(|d| {
57                serde_json::json!({
58                    "id": d.id,
59                    "name": d.name,
60                    "drive_type": d.drive_type,
61                    "site": {"id": site.id, "name": site.display_name, "url": site.web_url},
62                })
63            })
64            .collect();
65        rt.out.print_json(&serde_json::json!({
66            "total": total,
67            "next": null,
68            "items": items,
69        }));
70    } else {
71        for d in &all_drives {
72            rt.out
73                .print_data(&format!("{:30}  {:18}  {}", d.name, d.drive_type, d.id));
74        }
75        rt.out
76            .print_message(&format!("({total} drive(s) on {})", site.display_name));
77    }
78    Ok(())
79}