Simplify config: inline serde types, return Vec<Plugin> directly
Assisted-by: Claude Opus 4.6 via pi
change nuvlnnrtzllwzzxpqzotsnpvrnpnuynm
commit 37ca48b38bb9c0874c3e12cb94656b6b6058a086
author Alpha Chen <alpha@kejadlen.dev>
date
parent kmlmkuyq
diff --git a/src/config.rs b/src/config.rs
index a9d9193..4a6e0d0 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -4,35 +4,17 @@ use std::collections::HashSet;
 use color_eyre::eyre::{Context, Result, bail};
 use serde::Deserialize;
 
-#[derive(Debug, Deserialize)]
-pub struct ConfigFile {
-    #[serde(default)]
-    pub plugins: BTreeMap<String, PluginEntry>,
-}
-
-#[derive(Debug, Clone, Deserialize)]
-pub struct PluginEntry {
-    pub src: String,
-    pub r#ref: String,
-    /// Override path to marketplace.json within the repo.
-    /// Defaults to `.claude-plugin/marketplace.json`.
-    pub marketplace: Option<String>,
-}
-
 #[derive(Debug, Clone)]
 pub struct Plugin {
     pub name: String,
     pub src: String,
     pub r#ref: String,
+    /// Override path to marketplace.json within the repo.
+    /// Defaults to `.claude-plugin/marketplace.json`.
     pub marketplace: Option<String>,
 }
 
-#[derive(Debug)]
-pub struct Config {
-    pub plugins: Vec<Plugin>,
-}
-
-pub fn load() -> Result<Config> {
+pub fn load() -> Result<Vec<Plugin>> {
     let config_dir = crate::paths::config_dir();
 
     if !config_dir.is_dir() {
@@ -61,10 +43,24 @@ pub fn load() -> Result<Config> {
         let path = entry.path();
         let contents = std::fs::read_to_string(&path)
             .with_context(|| format!("failed to read {}", path.display()))?;
+
+        #[derive(Deserialize)]
+        struct PluginEntry {
+            src: String,
+            r#ref: String,
+            marketplace: Option<String>,
+        }
+
+        #[derive(Deserialize)]
+        struct ConfigFile {
+            #[serde(default)]
+            plugins: BTreeMap<String, PluginEntry>,
+        }
+
         let file: ConfigFile = serde_yml::from_str(&contents)
             .with_context(|| format!("failed to parse {}", path.display()))?;
 
-        for (name, plugin) in file.plugins {
+        for (name, entry) in file.plugins {
             if !seen_names.insert(name.clone()) {
                 bail!(
                     "duplicate plugin name '{}' (found in {})",
@@ -74,12 +70,12 @@ pub fn load() -> Result<Config> {
             }
             plugins.push(Plugin {
                 name,
-                src: plugin.src,
-                r#ref: plugin.r#ref,
-                marketplace: plugin.marketplace,
+                src: entry.src,
+                r#ref: entry.r#ref,
+                marketplace: entry.marketplace,
             });
         }
     }
 
-    Ok(Config { plugins })
+    Ok(plugins)
 }
diff --git a/src/main.rs b/src/main.rs
index e716227..d6c57b6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -73,16 +73,14 @@ fn main() -> Result<()> {
 }
 
 fn do_update(names: &[String]) -> Result<()> {
-    let config = config::load().context("failed to load config")?;
+    let all_plugins = config::load().context("failed to load config")?;
 
     let plugins: Vec<_> = if names.is_empty() {
-        config.plugins.clone()
+        all_plugins
     } else {
-        config
-            .plugins
-            .iter()
+        all_plugins
+            .into_iter()
             .filter(|p| names.contains(&p.name))
-            .cloned()
             .collect()
     };