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)]
force: bool,
/// List installable parsers
#[arg(short, long)]
list: bool,
languages: Vec<String>,
}
impl Install {
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 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();

View file

@ -16,6 +16,10 @@ pub type LanguageDefs = HashMap<String, InstallInfo>;
pub struct LanguageDb(Vec<LanguageDefs>);
impl LanguageDb {
pub fn new(sources: Vec<HashMap<String, InstallInfo>>) -> 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<HashMap<String, InstallInfo>>) -> Self {
Self(sources)
pub fn into_keys(self) -> impl Iterator<Item = String> {
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}")]
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<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 {
@ -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}"),
}