use crate::releases::impls;
use crate::Stable;
use rust_release::RustRelease;
#[derive(Debug, Default)]
pub struct StableReleases<C = ()>(impls::ReleasesImpl<Stable, C>);
impl<C> StableReleases<C> {
pub fn add(&mut self, release: RustRelease<Stable, C>) {
self.0.add(release);
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = &RustRelease<Stable, C>> {
self.0.iter()
}
pub fn merge_with<F>(self, right: StableReleases<C>, merge_fn: F) -> StableReleases<C>
where
F: Fn(RustRelease<Stable, C>, RustRelease<Stable, C>) -> RustRelease<Stable, C>,
{
StableReleases(self.0.merge_with(right.0, merge_fn))
}
}
impl StableReleases<()> {
pub fn merge(self, right: StableReleases<()>) -> StableReleases<()> {
self.merge_with(right, crate::merge::merge_default)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::merge::builder::MergeBuilder;
use rust_release::{
date::Date,
toolchain::{Channel, RustVersion, Target, Toolchain},
};
use std::collections::HashSet;
fn make_release(v: impl Into<RustVersion>, d: Option<Date>) -> RustRelease<Stable> {
let v = v.into();
RustRelease {
version: Stable::new(v.major(), v.minor(), v.patch()),
release_date: d.clone(),
toolchains: vec![make_toolchain(v, d, Target::host())],
context: (),
}
}
fn make_toolchain(v: impl Into<RustVersion>, d: Option<Date>, target: Target) -> Toolchain {
Toolchain::new(
Channel::stable(v.into()),
d,
target,
HashSet::new(),
HashSet::new(),
)
}
#[test]
fn two_unique_versions() {
let mut releases = StableReleases::default();
releases.add(make_release((1, 2, 3), None));
releases.add(make_release((4, 5, 6), None));
assert_eq!(releases.len(), 2);
let versions: Vec<_> = releases.iter().map(|r| &r.version).collect();
assert!(versions.contains(&&Stable::new(1, 2, 3)));
assert!(versions.contains(&&Stable::new(4, 5, 6)));
let toolchains: Vec<_> = releases.iter().map(|r| r.toolchains.len()).collect();
assert_eq!(toolchains, vec![1, 1]);
}
#[test]
fn two_matching_versions() {
let r1 = make_release((1, 2, 3), None);
let r2 = RustRelease {
version: Stable::new(1, 2, 3),
release_date: None,
toolchains: vec![make_toolchain(
(1u64, 2u64, 3u64),
None,
Target::from_target_triple_or_unknown("wasm32-unknown-unknown"),
)],
context: (),
};
let merged = MergeBuilder::new(r1, r2).finish();
let mut releases = StableReleases::default();
releases.add(merged);
assert_eq!(releases.len(), 1);
let versions: Vec<_> = releases.iter().map(|r| &r.version).collect();
assert_eq!(versions[0], &Stable::new(1, 2, 3));
assert_eq!(releases.iter().next().unwrap().toolchains.len(), 2);
}
#[test]
fn two_matching_versions_with_dedup_toolchains() {
let r1 = make_release((1, 2, 3), None);
let r2 = make_release((1, 2, 3), None);
let merged = MergeBuilder::new(r1, r2).finish();
let mut releases = StableReleases::default();
releases.add(merged);
assert_eq!(releases.len(), 1);
let versions: Vec<_> = releases.iter().map(|r| &r.version).collect();
assert_eq!(versions[0], &Stable::new(1, 2, 3));
assert_eq!(releases.iter().next().unwrap().toolchains.len(), 1);
}
#[test]
fn merge_overlapping_sets() {
let mut left = StableReleases::default();
left.add(make_release((1, 0, 0), None));
left.add(make_release((2, 0, 0), None));
let mut right = StableReleases::default();
right.add(make_release((2, 0, 0), None));
right.add(make_release((3, 0, 0), None));
let merged = left.merge(right);
assert_eq!(merged.len(), 3);
let versions: Vec<_> = merged.iter().map(|r| &r.version).collect();
assert!(versions.contains(&&Stable::new(1, 0, 0)));
assert!(versions.contains(&&Stable::new(2, 0, 0)));
assert!(versions.contains(&&Stable::new(3, 0, 0)));
}
}