Skip to main content

abbaye/version_extractors/
mod.rs

1use miette::{Result, bail};
2use serde::Deserialize;
3
4pub mod cargo;
5pub mod git;
6
7use cargo::{CargoVersion, CargoVersionConfig};
8use git::{GitVersion, GitVersionConfig};
9
10#[allow(async_fn_in_trait)]
11pub trait VersionExtractor {
12    type ConfigType: Default + for<'de> Deserialize<'de> + Clone;
13
14    async fn get_last_version(&self, config: Self::ConfigType) -> Result<String>;
15
16    async fn get_all_versions(&self, _config: Self::ConfigType) -> Result<Vec<String>> {
17        bail!("get_all_versions is not supported by this version extractor")
18    }
19}
20
21#[derive(Debug, Deserialize)]
22#[serde(tag = "type", rename_all = "snake_case")]
23pub enum AnyVersionExtractor {
24    /// Reads the version from the `version` field in the `[package]` section
25    /// of a `Cargo.toml` file.
26    ///
27    /// ```toml
28    /// [version_extractor]
29    /// type = "cargo"
30    /// manifest_path = "Cargo.toml" # optional, defaults to ./Cargo.toml
31    /// ```
32    Cargo(CargoVersionConfig),
33
34    /// Derives the version from the most recent Git tag using
35    /// `git describe --tags --always`.
36    /// Supports stripping a tag prefix (e.g. `"v"`) and customising the
37    /// suffix appended when the working tree has uncommitted changes.
38    ///
39    /// ```toml
40    /// [version_extractor]
41    /// type = "git"
42    /// tag_prefix = "v"      # optional, strips leading "v"
43    /// dirty_suffix = "-dev" # optional, defaults to "-dirty"
44    /// ```
45    Git(GitVersionConfig),
46}
47
48impl AnyVersionExtractor {
49    pub async fn extract(&self) -> Result<String> {
50        match self {
51            Self::Cargo(config) => CargoVersion.get_last_version(config.clone()).await,
52            Self::Git(config) => GitVersion.get_last_version(config.clone()).await,
53        }
54    }
55
56    pub async fn extract_all(&self) -> Result<Vec<String>> {
57        match self {
58            Self::Cargo(config) => CargoVersion.get_all_versions(config.clone()).await,
59            Self::Git(config) => GitVersion.get_all_versions(config.clone()).await,
60        }
61    }
62}