diff --git a/src/install.rs b/src/install.rs index a0de8bd..8ecbbaa 100644 --- a/src/install.rs +++ b/src/install.rs @@ -18,15 +18,32 @@ pub struct Install { #[arg(short, long)] force: bool, + /// List installable parsers + #[arg(short, long)] + list: bool, + languages: Vec, } impl Install { pub fn run(self, mut settings: Settings) -> anyhow::Result { + let language_defs = settings.language_defs()?; + + if self.list { + let mut available = language_defs.into_keys().collect::>(); + available.sort(); + available.dedup(); + + for language in available { + println!("{language}"); + } + + return Ok(ExitCode::SUCCESS); + } + let src_dir = tempdir()?; let parser_dir = settings.parser_dir(); - let language_defs = settings.language_defs()?; let InstallSettings { compiler } = settings.install; create_dir_all(&parser_dir)?; @@ -37,6 +54,7 @@ impl Install { let Self { mut languages, force, + .. } = self; languages.sort(); diff --git a/src/install/languages.rs b/src/install/languages.rs index b3f654e..8e7ed30 100644 --- a/src/install/languages.rs +++ b/src/install/languages.rs @@ -16,6 +16,10 @@ pub type LanguageDefs = HashMap; pub struct LanguageDb(Vec); impl LanguageDb { + pub fn new(sources: Vec>) -> Self { + Self(sources) + } + pub fn get(&self, language: &str) -> Option<&InstallInfo> { for source in &self.0 { if let Some(info) = source.get(language) { @@ -25,8 +29,8 @@ impl LanguageDb { None } - pub fn new(sources: Vec>) -> Self { - Self(sources) + pub fn into_keys(self) -> impl Iterator { + self.0.into_iter().flat_map(HashMap::into_keys) } } diff --git a/src/settings.rs b/src/settings.rs index a259bf1..8dddc9c 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -56,12 +56,15 @@ pub enum Error { #[error("unable to read config file: {0}")] Io(#[from] io::Error), - #[error(transparent)] - Toml(#[from] toml::de::Error), + #[error("{file:?}: {e}")] + Toml { file: PathBuf, e: toml::de::Error }, } pub fn get_settings(path: &Path) -> Result { - Ok(toml::from_str(&read_to_string(path)?)?) + toml::from_str(&read_to_string(path)?).map_err(|e| Error::Toml { + file: path.to_owned(), + e, + }) } impl Settings { @@ -76,7 +79,12 @@ impl Settings { let default_path = self.data_dir.join("languages.toml"); match read_to_string(&default_path) { - Ok(default_defs) => sources.push(toml::from_str(&default_defs)?), + Ok(default_defs) => { + sources.push(toml::from_str(&default_defs).map_err(|e| Error::Toml { + file: default_path, + e, + })?) + } Err(e) => warning!("couldn't read language install info from {default_path:?}: {e}"), }