<commit_before>use std::str::FromStr;

use super::errors::*;

/// Additional version functionality
pub trait VersionExt {
    /// Increments the major version number for this Version.
    fn increment_major(&mut self);
    /// Increments the minor version number for this Version.
    fn increment_minor(&mut self);
    /// Increments the patch version number for this Version.
    fn increment_patch(&mut self);
    /// Increment the alpha pre-release number for this Version.
    ///
    /// If this isn't alpha, switch to it.
    ///
    /// Errors if this would decrement the pre-release phase.
    fn increment_alpha(&mut self) -> CargoResult<()>;
    /// Increment the beta pre-release number for this Version.
    ///
    /// If this isn't beta, switch to it.
    ///
    /// Errors if this would decrement the pre-release phase.
    fn increment_beta(&mut self) -> CargoResult<()>;
    /// Increment the rc pre-release number for this Version.
    ///
    /// If this isn't rc, switch to it.
    ///
    /// Errors if this would decrement the pre-release phase.
    fn increment_rc(&mut self) -> CargoResult<()>;
    /// Append informational-only metadata.
    fn metadata(&mut self, metadata: &str) -> CargoResult<()>;
    /// Checks to see if the current Version is in pre-release status
    fn is_prerelease(&self) -> bool;
}

impl VersionExt for semver::Version {
    fn increment_major(&mut self) {
        self.major += 1;
        self.minor = 0;
        self.patch = 0;
        self.pre = semver::Prerelease::EMPTY;
        self.build = semver::BuildMetadata::EMPTY;
    }

    fn increment_minor(&mut self) {
        self.minor += 1;
        self.patch = 0;
        self.pre = semver::Prerelease::EMPTY;
        self.build = semver::BuildMetadata::EMPTY;
    }

    fn increment_patch(&mut self) {
        self.patch += 1;
        self.pre = semver::Prerelease::EMPTY;
        self.build = semver::BuildMetadata::EMPTY;
    }

    fn increment_alpha(&mut self) -> CargoResult<()> {
        if let Some((pre_ext, pre_ext_ver)) = prerelease_id_version(self)? {
            if pre_ext == VERSION_BETA || pre_ext == VERSION_RC {
                Err(invalid_release_level(VERSION_ALPHA, self.clone()))
            } else {
                let new_ext_ver = if pre_ext == VERSION_ALPHA {
                    pre_ext_ver.unwrap_or(0) + 1
                } else {
                    1
                };
                self.pre = semver::Prerelease::new(&format!("{}.{}", VERSION_ALPHA, new_ext_ver))?;
                Ok(())
            }
        } else {
            self.increment_patch();
            self.pre = semver::Prerelease::new(&format!("{}.1", VERSION_ALPHA))?;
            Ok(())
        }
    }

    fn increment_beta(&mut self) -> CargoResult<()> {
        if let Some((pre_ext, pre_ext_ver)) = prerelease_id_version(self)? {
            if pre_ext == VERSION_RC {
                Err(invalid_release_level(VERSION_BETA, self.clone()))
            } else {
                let new_ext_ver = if pre_ext == VERSION_BETA {
                    pre_ext_ver.unwrap_or(0) + 1
                } else {
                    1
                };
                self.pre = semver::Prerelease::new(&format!("{}.{}", VERSION_BETA, new_ext_ver))?;
                Ok(())
            }
        } else {
            self.increment_patch();
            self.pre = semver::Prerelease::new(&format!("{}.1", VERSION_BETA))?;
            Ok(())
        }
    }

    fn increment_rc(&mut self) -> CargoResult<()> {
        if let Some((pre_ext, pre_ext_ver)) = prerelease_id_version(self)? {
            let new_ext_ver = if pre_ext == VERSION_RC {
                pre_ext_ver.unwrap_or(0) + 1
            } else {
                1
            };
            self.pre = semver::Prerelease::new(&format!("{}.{}", VERSION_RC, new_ext_ver))?;
            Ok(())
        } else {
            self.increment_patch();
            self.pre = semver::Prerelease::new(&format!("{}.1", VERSION_RC))?;
            Ok(())
        }
    }

    fn metadata(&mut self, build: &str) -> CargoResult<()> {
        self.build = semver::BuildMetadata::new(build)?;
        Ok(())
    }

    fn is_prerelease(&self) -> bool {
        !self.pre.is_empty()
    }
}

static VERSION_ALPHA: &str = "alpha";
static VERSION_BETA: &str = "beta";
static VERSION_RC: &str = "rc";

fn prerelease_id_version(version: &semver::Version) -> CargoResult<Option<(String, Option<u64>)>> {
    if !version.pre.is_empty() {
        if let Some((alpha, numeric)) = version.pre.as_str().split_once(".") {
            let alpha = alpha.to_owned();
            let numeric = u64::from_str(numeric)
                .map_err(|_| anyhow::format_err!("This version scheme is not supported. Use format like `pre`, `dev` or `alpha.1` for prerelease symbol"))?;
            Ok(Some((alpha, Some(numeric))))
        } else {
            Ok(Some((version.pre.as_str().to_owned(), None)))
        }
    } else {
        Ok(None)<commit_msg>style: Address clippy<commit_after>use std::str::FromStr;

use super::errors::*;

/// Additional version functionality
pub trait VersionExt {
    /// Increments the major version number for this Version.
    fn increment_major(&mut self);
    /// Increments the minor version number for this Version.
    fn increment_minor(&mut self);
    /// Increments the patch version number for this Version.
    fn increment_patch(&mut self);
    /// Increment the alpha pre-release number for this Version.
    ///
    /// If this isn't alpha, switch to it.
    ///
    /// Errors if this would decrement the pre-release phase.
    fn increment_alpha(&mut self) -> CargoResult<()>;
    /// Increment the beta pre-release number for this Version.
    ///
    /// If this isn't beta, switch to it.
    ///
    /// Errors if this would decrement the pre-release phase.
    fn increment_beta(&mut self) -> CargoResult<()>;
    /// Increment the rc pre-release number for this Version.
    ///
    /// If this isn't rc, switch to it.
    ///
    /// Errors if this would decrement the pre-release phase.
    fn increment_rc(&mut self) -> CargoResult<()>;
    /// Append informational-only metadata.
    fn metadata(&mut self, metadata: &str) -> CargoResult<()>;
    /// Checks to see if the current Version is in pre-release status
    fn is_prerelease(&self) -> bool;
}

impl VersionExt for semver::Version {
    fn increment_major(&mut self) {
        self.major += 1;
        self.minor = 0;
        self.patch = 0;
        self.pre = semver::Prerelease::EMPTY;
        self.build = semver::BuildMetadata::EMPTY;
    }

    fn increment_minor(&mut self) {
        self.minor += 1;
        self.patch = 0;
        self.pre = semver::Prerelease::EMPTY;
        self.build = semver::BuildMetadata::EMPTY;
    }

    fn increment_patch(&mut self) {
        self.patch += 1;
        self.pre = semver::Prerelease::EMPTY;
        self.build = semver::BuildMetadata::EMPTY;
    }

    fn increment_alpha(&mut self) -> CargoResult<()> {
        if let Some((pre_ext, pre_ext_ver)) = prerelease_id_version(self)? {
            if pre_ext == VERSION_BETA || pre_ext == VERSION_RC {
                Err(invalid_release_level(VERSION_ALPHA, self.clone()))
            } else {
                let new_ext_ver = if pre_ext == VERSION_ALPHA {
                    pre_ext_ver.unwrap_or(0) + 1
                } else {
                    1
                };
                self.pre = semver::Prerelease::new(&format!("{}.{}", VERSION_ALPHA, new_ext_ver))?;
                Ok(())
            }
        } else {
            self.increment_patch();
            self.pre = semver::Prerelease::new(&format!("{}.1", VERSION_ALPHA))?;
            Ok(())
        }
    }

    fn increment_beta(&mut self) -> CargoResult<()> {
        if let Some((pre_ext, pre_ext_ver)) = prerelease_id_version(self)? {
            if pre_ext == VERSION_RC {
                Err(invalid_release_level(VERSION_BETA, self.clone()))
            } else {
                let new_ext_ver = if pre_ext == VERSION_BETA {
                    pre_ext_ver.unwrap_or(0) + 1
                } else {
                    1
                };
                self.pre = semver::Prerelease::new(&format!("{}.{}", VERSION_BETA, new_ext_ver))?;
                Ok(())
            }
        } else {
            self.increment_patch();
            self.pre = semver::Prerelease::new(&format!("{}.1", VERSION_BETA))?;
            Ok(())
        }
    }

    fn increment_rc(&mut self) -> CargoResult<()> {
        if let Some((pre_ext, pre_ext_ver)) = prerelease_id_version(self)? {
            let new_ext_ver = if pre_ext == VERSION_RC {
                pre_ext_ver.unwrap_or(0) + 1
            } else {
                1
            };
            self.pre = semver::Prerelease::new(&format!("{}.{}", VERSION_RC, new_ext_ver))?;
            Ok(())
        } else {
            self.increment_patch();
            self.pre = semver::Prerelease::new(&format!("{}.1", VERSION_RC))?;
            Ok(())
        }
    }

    fn metadata(&mut self, build: &str) -> CargoResult<()> {
        self.build = semver::BuildMetadata::new(build)?;
        Ok(())
    }

    fn is_prerelease(&self) -> bool {
        !self.pre.is_empty()
    }
}

static VERSION_ALPHA: &str = "alpha";
static VERSION_BETA: &str = "beta";
static VERSION_RC: &str = "rc";

fn prerelease_id_version(version: &semver::Version) -> CargoResult<Option<(String, Option<u64>)>> {
    if !version.pre.is_empty() {
        if let Some((alpha, numeric)) = version.pre.as_str().split_once('.') {
            let alpha = alpha.to_owned();
            let numeric = u64::from_str(numeric)
                .map_err(|_| anyhow::format_err!("This version scheme is not supported. Use format like `pre`, `dev` or `alpha.1` for prerelease symbol"))?;
            Ok(Some((alpha, Some(numeric))))
        } else {
            Ok(Some((version.pre.as_str().to_owned(), None)))
        }
    } else {
        Ok(None)
{'fraction_non_alphanumeric': 0.1434721665999199, 'fraction_numerical': 0.00460552663195835, 'mean_word_length': 2.0150920615756114, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6366898', 'n_tokens_mistral': 3135, 'n_tokens_neox': 3068, 'n_words': 705}