sharepoint_cli/commands/
drives.rs1use 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 {
12 site,
13 limit,
14 all,
15 fields,
16 } => list(rt, &site, limit, all, &fields).await,
17 }
18}
19
20async fn list(
21 rt: &Runtime,
22 site_input: &str,
23 limit: usize,
24 all: bool,
25 fields: &[String],
26) -> Result<()> {
27 let auth = AuthContext::new(rt.cfg.clone(), rt.cache_path.clone());
28 let graph = GraphClient::new(auth);
29
30 let site_ref = if site_input == "default" {
32 SiteRef::Default
33 } else if site_input.starts_with("http://") || site_input.starts_with("https://") {
34 SiteRef::Url(site_input.to_string())
35 } else if let Some(rest) = site_input.strip_prefix("spo://") {
36 let name = rest
38 .split('/')
39 .next()
40 .filter(|s| !s.is_empty())
41 .ok_or_else(|| {
42 CliError::Input(
43 "spo:// URI is missing a site name (expected spo://SiteName)".into(),
44 )
45 })?;
46 SiteRef::Name(name.to_string())
47 } else {
48 SiteRef::Name(site_input.to_string())
49 };
50
51 let site = sites::resolve(
52 &graph,
53 &site_ref,
54 &rt.cfg.site_aliases,
55 rt.cfg.default_site.as_deref(),
56 )
57 .await?;
58 let mut all_drives = drives::list_drives(&graph, &site.id).await?;
59 let total = all_drives.len();
60 if !all && all_drives.len() > limit {
61 all_drives.truncate(limit);
62 }
63
64 if rt.out.json {
65 let items: Vec<_> = all_drives
66 .iter()
67 .map(|d| {
68 filter_fields(
69 serde_json::json!({
70 "id": d.id,
71 "name": d.name,
72 "drive_type": d.drive_type,
73 "site": {"id": site.id, "name": site.display_name, "url": site.web_url},
74 }),
75 fields,
76 )
77 })
78 .collect();
79 rt.out.print_json(&serde_json::json!({
80 "total": total,
81 "next": null,
82 "items": items,
83 }));
84 } else {
85 for d in &all_drives {
86 rt.out
87 .print_data(&format!("{:30} {:18} {}", d.name, d.drive_type, d.id));
88 }
89 rt.out
90 .print_message(&format!("({total} drive(s) on {})", site.display_name));
91 }
92 Ok(())
93}
94
95fn filter_fields(mut value: serde_json::Value, fields: &[String]) -> serde_json::Value {
97 if fields.is_empty() {
98 return value;
99 }
100 if let serde_json::Value::Object(ref mut map) = value {
101 map.retain(|k, _| fields.iter().any(|f| f == k));
102 }
103 value
104}