use {
super::{determine_semver_range, get_huge, get_raw_without_range, parser, regexes, semver_range::SemverRange},
log::debug,
node_semver::{Range, Version},
};
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum BasicSemverVariant {
Latest,
Major,
Minor,
Patch,
}
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
pub struct BasicSemver {
pub raw: String,
pub variant: BasicSemverVariant,
pub range_variant: SemverRange,
pub node_range: Range,
pub node_version: Version,
}
impl BasicSemver {
pub fn new(value: &str) -> Option<Self> {
Range::parse(value).ok().and_then(|node_range| {
let raw = value.to_string();
let huge = get_huge().to_string();
if parser::is_exact(value) {
let range_variant = SemverRange::Exact;
Some(BasicSemver {
raw,
variant: BasicSemverVariant::Patch,
range_variant,
node_range,
node_version: Version::parse(value).unwrap(),
})
} else if parser::is_range(value) {
let range_variant = determine_semver_range(value).unwrap();
let exact = get_raw_without_range(value);
let node_version = Version::parse(exact).unwrap();
Some(BasicSemver {
raw,
variant: BasicSemverVariant::Patch,
range_variant,
node_range,
node_version,
})
} else if parser::is_major(value) {
let range_variant = SemverRange::Exact;
let major = format!("{value}.{huge}.{huge}");
let node_version = Version::parse(major).unwrap();
Some(BasicSemver {
raw,
variant: BasicSemverVariant::Major,
range_variant,
node_range,
node_version,
})
} else if parser::is_range_major(value) {
let range_variant = determine_semver_range(value).unwrap();
let exact = regexes::RANGE_CHARS.replace(value, "");
let major = format!("{exact}.{huge}.{huge}");
let node_version = Version::parse(major).unwrap();
Some(BasicSemver {
raw,
variant: BasicSemverVariant::Major,
range_variant,
node_range,
node_version,
})
} else if parser::is_minor(value) {
let range_variant = SemverRange::Exact;
let minor = format!("{value}.{huge}");
let node_version = Version::parse(minor).unwrap();
Some(BasicSemver {
raw,
variant: BasicSemverVariant::Minor,
range_variant,
node_range,
node_version,
})
} else if parser::is_range_minor(value) {
let range_variant = determine_semver_range(value).unwrap();
let exact = regexes::RANGE_CHARS.replace(value, "");
let minor = format!("{exact}.{huge}");
let node_version = Version::parse(minor).unwrap();
Some(BasicSemver {
raw,
variant: BasicSemverVariant::Minor,
range_variant,
node_range,
node_version,
})
} else if parser::is_latest(value) {
let range_variant = SemverRange::Any;
let latest = format!("{huge}.{huge}.{huge}");
let node_version = Version::parse(latest).unwrap();
Some(BasicSemver {
raw,
variant: BasicSemverVariant::Latest,
range_variant,
node_range,
node_version,
})
} else {
None
}
})
}
pub fn with_range(self, range: &SemverRange) -> Self {
let range_str = range.unwrap();
match self.variant {
BasicSemverVariant::Latest => {
debug!("Cannot apply semver range '{:?}' to specifier '{}'", range, self.raw);
self
}
BasicSemverVariant::Major => {
let major = self.node_version.major;
Self::new(&format!("{range_str}{major}")).unwrap()
}
BasicSemverVariant::Minor => {
let major = self.node_version.major;
let minor = self.node_version.minor;
Self::new(&format!("{range_str}{major}.{minor}")).unwrap()
}
BasicSemverVariant::Patch => {
let patch = self.node_version.to_string();
Self::new(&format!("{range_str}{patch}")).unwrap()
}
}
}
pub fn with_semver(self, semver: &BasicSemver) -> Self {
semver.clone()
}
}