list available languages + better error reporting

This commit is contained in:
wires 2025-03-23 16:41:25 -04:00
parent fa0f908db8
commit 674b1b8fbe
Signed by: wires
SSH key fingerprint: SHA256:9GtP+M3O2IivPDlw1UY872UPUuJH2gI0yG6ExBxaaiM
3 changed files with 37 additions and 7 deletions

View file

@ -18,15 +18,32 @@ pub struct Install {
#[arg(short, long)] #[arg(short, long)]
force: bool, force: bool,
/// List installable parsers
#[arg(short, long)]
list: bool,
languages: Vec<String>, languages: Vec<String>,
} }
impl Install { impl Install {
pub fn run(self, mut settings: Settings) -> anyhow::Result<ExitCode> { pub fn run(self, mut settings: Settings) -> anyhow::Result<ExitCode> {
let language_defs = settings.language_defs()?;
if self.list {
let mut available = language_defs.into_keys().collect::<Vec<_>>();
available.sort();
available.dedup();
for language in available {
println!("{language}");
}
return Ok(ExitCode::SUCCESS);
}
let src_dir = tempdir()?; let src_dir = tempdir()?;
let parser_dir = settings.parser_dir(); let parser_dir = settings.parser_dir();
let language_defs = settings.language_defs()?;
let InstallSettings { compiler } = settings.install; let InstallSettings { compiler } = settings.install;
create_dir_all(&parser_dir)?; create_dir_all(&parser_dir)?;
@ -37,6 +54,7 @@ impl Install {
let Self { let Self {
mut languages, mut languages,
force, force,
..
} = self; } = self;
languages.sort(); languages.sort();

View file

@ -16,6 +16,10 @@ pub type LanguageDefs = HashMap<String, InstallInfo>;
pub struct LanguageDb(Vec<LanguageDefs>); pub struct LanguageDb(Vec<LanguageDefs>);
impl LanguageDb { impl LanguageDb {
pub fn new(sources: Vec<HashMap<String, InstallInfo>>) -> Self {
Self(sources)
}
pub fn get(&self, language: &str) -> Option<&InstallInfo> { pub fn get(&self, language: &str) -> Option<&InstallInfo> {
for source in &self.0 { for source in &self.0 {
if let Some(info) = source.get(language) { if let Some(info) = source.get(language) {
@ -25,8 +29,8 @@ impl LanguageDb {
None None
} }
pub fn new(sources: Vec<HashMap<String, InstallInfo>>) -> Self { pub fn into_keys(self) -> impl Iterator<Item = String> {
Self(sources) self.0.into_iter().flat_map(HashMap::into_keys)
} }
} }

View file

@ -56,12 +56,15 @@ pub enum Error {
#[error("unable to read config file: {0}")] #[error("unable to read config file: {0}")]
Io(#[from] io::Error), Io(#[from] io::Error),
#[error(transparent)] #[error("{file:?}: {e}")]
Toml(#[from] toml::de::Error), Toml { file: PathBuf, e: toml::de::Error },
} }
pub fn get_settings(path: &Path) -> Result<Settings, Error> { pub fn get_settings(path: &Path) -> Result<Settings, Error> {
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 { impl Settings {
@ -76,7 +79,12 @@ impl Settings {
let default_path = self.data_dir.join("languages.toml"); let default_path = self.data_dir.join("languages.toml");
match read_to_string(&default_path) { 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}"), Err(e) => warning!("couldn't read language install info from {default_path:?}: {e}"),
} }