use rust_release::RustRelease;
use std::collections::BTreeSet;
mod beta;
mod nightly;
mod stable;
pub use beta::BetaReleases;
pub use nightly::NightlyReleases;
pub use stable::StableReleases;
pub(in crate::releases) mod impls {
use super::*;
use std::fmt::Debug;
#[derive(Debug)]
pub struct ReleasesImpl<V: Debug, C> {
releases: BTreeSet<RustRelease<V, C>>,
}
impl<V: Debug, C> Default for ReleasesImpl<V, C> {
fn default() -> Self {
Self {
releases: BTreeSet::default(),
}
}
}
impl<V: Debug, C> ReleasesImpl<V, C>
where
V: Ord,
{
pub fn add(&mut self, release: RustRelease<V, C>) {
self.releases.insert(release);
}
pub fn len(&self) -> usize {
self.releases.len()
}
pub fn is_empty(&self) -> bool {
self.releases.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = &RustRelease<V, C>> {
self.releases.iter()
}
pub fn merge_with<F>(self, right: Self, merge_fn: F) -> Self
where
V: Ord,
F: Fn(RustRelease<V, C>, RustRelease<V, C>) -> RustRelease<V, C>,
{
let mut result = BTreeSet::new();
let mut others = right.releases;
for release in self.releases {
if let Some(other_release) = others.take(&release) {
result.insert(merge_fn(release, other_release));
} else {
result.insert(release);
}
}
result.extend(others);
Self { releases: result }
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Stable;
#[test]
fn merge_with_is_additive() {
let mut left = ReleasesImpl::default();
left.add(RustRelease::new(Stable::new(1, 0, 0), None, []));
let mut right = ReleasesImpl::default();
right.add(RustRelease::new(Stable::new(2, 0, 0), None, []));
let merged = left.merge_with(right, |_l, _r| panic!("must not be called"));
assert_eq!(merged.len(), 2);
}
}
}