use crate::celt_redundancy::RedundancyDecision;
use crate::framing::{OperatingMode, SilkBandwidth};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BoundaryOp {
SilkReset,
SilkAndCeltReset,
CeltReset,
WindowedCrossLap,
DirectMix,
CeltOverlapExtract,
PacketLossConcealment,
StreamJoin,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NormativeTransition {
SilkToSilkWithRedundancy,
NbOrMbSilkToHybridWithRedundancy,
WbSilkToHybrid,
SilkToCeltWithRedundancy,
HybridToNbOrMbSilkWithRedundancy,
HybridToWbSilk,
HybridToCeltWithRedundancy,
CeltToSilkWithRedundancy,
CeltToHybridWithRedundancy,
}
impl NormativeTransition {
pub fn seam_operations(self) -> &'static [BoundaryOp] {
use BoundaryOp::*;
match self {
Self::SilkToSilkWithRedundancy => {
&[WindowedCrossLap, CeltReset, WindowedCrossLap, SilkReset]
}
Self::NbOrMbSilkToHybridWithRedundancy => &[WindowedCrossLap, CeltReset, SilkReset],
Self::WbSilkToHybrid => &[CeltReset],
Self::SilkToCeltWithRedundancy => &[WindowedCrossLap, CeltReset],
Self::HybridToNbOrMbSilkWithRedundancy => {
&[WindowedCrossLap, CeltReset, WindowedCrossLap, SilkReset]
}
Self::HybridToWbSilk => &[CeltOverlapExtract, DirectMix, StreamJoin],
Self::HybridToCeltWithRedundancy => &[WindowedCrossLap, CeltReset],
Self::CeltToSilkWithRedundancy => &[WindowedCrossLap, SilkReset],
Self::CeltToHybridWithRedundancy => &[WindowedCrossLap, SilkAndCeltReset],
}
}
pub fn carries_redundancy(self) -> bool {
matches!(
self,
Self::SilkToSilkWithRedundancy
| Self::NbOrMbSilkToHybridWithRedundancy
| Self::SilkToCeltWithRedundancy
| Self::HybridToNbOrMbSilkWithRedundancy
| Self::HybridToCeltWithRedundancy
| Self::CeltToSilkWithRedundancy
| Self::CeltToHybridWithRedundancy
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RecommendedNonNormativeTransition {
SilkToSilkAudioBandwidthChange,
NbOrMbSilkToHybrid,
SilkToCeltWithoutRedundancy,
HybridToNbOrMbSilk,
HybridToCeltWithoutRedundancy,
CeltToSilkWithoutRedundancy,
CeltToHybridWithoutRedundancy,
}
impl RecommendedNonNormativeTransition {
pub fn seam_operations(self) -> &'static [BoundaryOp] {
use BoundaryOp::*;
match self {
Self::SilkToSilkAudioBandwidthChange => &[SilkReset],
Self::NbOrMbSilkToHybrid => &[SilkAndCeltReset],
Self::SilkToCeltWithoutRedundancy => {
&[PacketLossConcealment, WindowedCrossLap, CeltReset]
}
Self::HybridToNbOrMbSilk => &[CeltOverlapExtract, DirectMix, SilkReset],
Self::HybridToCeltWithoutRedundancy => {
&[PacketLossConcealment, WindowedCrossLap, CeltReset]
}
Self::CeltToSilkWithoutRedundancy => {
&[PacketLossConcealment, WindowedCrossLap, SilkReset]
}
Self::CeltToHybridWithoutRedundancy => {
&[PacketLossConcealment, WindowedCrossLap, SilkAndCeltReset]
}
}
}
}
pub fn classify_normative_transition(
prev_mode: OperatingMode,
prev_silk_bandwidth: Option<SilkBandwidth>,
next_mode: OperatingMode,
next_silk_bandwidth: Option<SilkBandwidth>,
redundancy_present: bool,
) -> Option<NormativeTransition> {
use OperatingMode::*;
match (prev_mode, next_mode, redundancy_present) {
(SilkOnly, SilkOnly, true) => match (prev_silk_bandwidth, next_silk_bandwidth) {
(Some(a), Some(b)) if a != b => Some(NormativeTransition::SilkToSilkWithRedundancy),
_ => None,
},
(SilkOnly, Hybrid, true) => match prev_silk_bandwidth {
Some(SilkBandwidth::Nb) | Some(SilkBandwidth::Mb) => {
Some(NormativeTransition::NbOrMbSilkToHybridWithRedundancy)
}
_ => None,
},
(SilkOnly, Hybrid, false) => match prev_silk_bandwidth {
Some(SilkBandwidth::Wb) => Some(NormativeTransition::WbSilkToHybrid),
_ => None,
},
(SilkOnly, CeltOnly, true) => Some(NormativeTransition::SilkToCeltWithRedundancy),
(Hybrid, SilkOnly, true) => match next_silk_bandwidth {
Some(SilkBandwidth::Nb) | Some(SilkBandwidth::Mb) => {
Some(NormativeTransition::HybridToNbOrMbSilkWithRedundancy)
}
_ => None,
},
(Hybrid, SilkOnly, false) => match next_silk_bandwidth {
Some(SilkBandwidth::Wb) => Some(NormativeTransition::HybridToWbSilk),
_ => None,
},
(Hybrid, CeltOnly, true) => Some(NormativeTransition::HybridToCeltWithRedundancy),
(CeltOnly, SilkOnly, true) => Some(NormativeTransition::CeltToSilkWithRedundancy),
(CeltOnly, Hybrid, true) => Some(NormativeTransition::CeltToHybridWithRedundancy),
_ => None,
}
}
pub fn recommended_non_normative(
prev_mode: OperatingMode,
prev_silk_bandwidth: Option<SilkBandwidth>,
next_mode: OperatingMode,
next_silk_bandwidth: Option<SilkBandwidth>,
) -> Option<RecommendedNonNormativeTransition> {
use OperatingMode::*;
match (prev_mode, next_mode) {
(SilkOnly, SilkOnly) => match (prev_silk_bandwidth, next_silk_bandwidth) {
(Some(a), Some(b)) if a != b => {
Some(RecommendedNonNormativeTransition::SilkToSilkAudioBandwidthChange)
}
_ => None,
},
(SilkOnly, Hybrid) => match prev_silk_bandwidth {
Some(SilkBandwidth::Nb) | Some(SilkBandwidth::Mb) => {
Some(RecommendedNonNormativeTransition::NbOrMbSilkToHybrid)
}
_ => None,
},
(SilkOnly, CeltOnly) => {
Some(RecommendedNonNormativeTransition::SilkToCeltWithoutRedundancy)
}
(Hybrid, SilkOnly) => match next_silk_bandwidth {
Some(SilkBandwidth::Nb) | Some(SilkBandwidth::Mb) => {
Some(RecommendedNonNormativeTransition::HybridToNbOrMbSilk)
}
_ => None,
},
(Hybrid, CeltOnly) => {
Some(RecommendedNonNormativeTransition::HybridToCeltWithoutRedundancy)
}
(CeltOnly, SilkOnly) => {
Some(RecommendedNonNormativeTransition::CeltToSilkWithoutRedundancy)
}
(CeltOnly, Hybrid) => {
Some(RecommendedNonNormativeTransition::CeltToHybridWithoutRedundancy)
}
(CeltOnly, CeltOnly) | (Hybrid, Hybrid) => None,
}
}
pub fn redundancy_is_present(decision: RedundancyDecision) -> bool {
decision.is_present()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::celt_redundancy::{RedundancyDecision, RedundancyPosition};
fn present() -> RedundancyDecision {
RedundancyDecision::Present {
position: RedundancyPosition::End,
size_bytes: 2,
}
}
fn invalid() -> RedundancyDecision {
RedundancyDecision::Invalid
}
fn not_present() -> RedundancyDecision {
RedundancyDecision::NotPresent
}
#[test]
fn row1_silk_to_silk_with_redundancy() {
let t = classify_normative_transition(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Nb),
OperatingMode::SilkOnly,
Some(SilkBandwidth::Mb),
true,
);
assert_eq!(t, Some(NormativeTransition::SilkToSilkWithRedundancy));
}
#[test]
fn row1_silk_to_silk_without_redundancy_is_not_normative() {
let t = classify_normative_transition(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Nb),
OperatingMode::SilkOnly,
Some(SilkBandwidth::Mb),
false,
);
assert_eq!(t, None);
}
#[test]
fn row2_nb_silk_to_hybrid_with_redundancy() {
let t = classify_normative_transition(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Nb),
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
true,
);
assert_eq!(
t,
Some(NormativeTransition::NbOrMbSilkToHybridWithRedundancy)
);
}
#[test]
fn row2_mb_silk_to_hybrid_with_redundancy() {
let t = classify_normative_transition(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Mb),
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
true,
);
assert_eq!(
t,
Some(NormativeTransition::NbOrMbSilkToHybridWithRedundancy)
);
}
#[test]
fn row3_wb_silk_to_hybrid_without_redundancy() {
let t = classify_normative_transition(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
false,
);
assert_eq!(t, Some(NormativeTransition::WbSilkToHybrid));
}
#[test]
fn row3_wb_silk_to_hybrid_with_redundancy_is_not_normative() {
let t = classify_normative_transition(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
true,
);
assert_eq!(t, None);
}
#[test]
fn row4_silk_to_celt_with_redundancy() {
let t = classify_normative_transition(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
OperatingMode::CeltOnly,
None,
true,
);
assert_eq!(t, Some(NormativeTransition::SilkToCeltWithRedundancy));
}
#[test]
fn row5_hybrid_to_nb_silk_with_redundancy() {
let t = classify_normative_transition(
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
OperatingMode::SilkOnly,
Some(SilkBandwidth::Nb),
true,
);
assert_eq!(
t,
Some(NormativeTransition::HybridToNbOrMbSilkWithRedundancy)
);
}
#[test]
fn row5_hybrid_to_mb_silk_with_redundancy() {
let t = classify_normative_transition(
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
OperatingMode::SilkOnly,
Some(SilkBandwidth::Mb),
true,
);
assert_eq!(
t,
Some(NormativeTransition::HybridToNbOrMbSilkWithRedundancy)
);
}
#[test]
fn row6_hybrid_to_wb_silk_without_redundancy() {
let t = classify_normative_transition(
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
false,
);
assert_eq!(t, Some(NormativeTransition::HybridToWbSilk));
}
#[test]
fn row7_hybrid_to_celt_with_redundancy() {
let t = classify_normative_transition(
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
OperatingMode::CeltOnly,
None,
true,
);
assert_eq!(t, Some(NormativeTransition::HybridToCeltWithRedundancy));
}
#[test]
fn row8_celt_to_silk_with_redundancy() {
let t = classify_normative_transition(
OperatingMode::CeltOnly,
None,
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
true,
);
assert_eq!(t, Some(NormativeTransition::CeltToSilkWithRedundancy));
}
#[test]
fn row9_celt_to_hybrid_with_redundancy() {
let t = classify_normative_transition(
OperatingMode::CeltOnly,
None,
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
true,
);
assert_eq!(t, Some(NormativeTransition::CeltToHybridWithRedundancy));
}
#[test]
fn seam_ops_row1_silk_to_silk() {
let ops = NormativeTransition::SilkToSilkWithRedundancy.seam_operations();
assert_eq!(
ops,
&[
BoundaryOp::WindowedCrossLap,
BoundaryOp::CeltReset,
BoundaryOp::WindowedCrossLap,
BoundaryOp::SilkReset,
]
);
}
#[test]
fn seam_ops_row3_wb_silk_to_hybrid() {
let ops = NormativeTransition::WbSilkToHybrid.seam_operations();
assert_eq!(ops, &[BoundaryOp::CeltReset]);
}
#[test]
fn seam_ops_row4_silk_to_celt_does_not_reset_following_celt() {
let ops = NormativeTransition::SilkToCeltWithRedundancy.seam_operations();
assert_eq!(ops, &[BoundaryOp::WindowedCrossLap, BoundaryOp::CeltReset]);
assert_eq!(
ops.iter()
.filter(|op| matches!(op, BoundaryOp::CeltReset))
.count(),
1
);
}
#[test]
fn seam_ops_row6_hybrid_to_wb_silk_uses_direct_mix_not_cross_lap() {
let ops = NormativeTransition::HybridToWbSilk.seam_operations();
assert_eq!(
ops,
&[
BoundaryOp::CeltOverlapExtract,
BoundaryOp::DirectMix,
BoundaryOp::StreamJoin,
]
);
assert!(!ops.contains(&BoundaryOp::WindowedCrossLap));
assert!(!ops.contains(&BoundaryOp::CeltReset));
assert!(!ops.contains(&BoundaryOp::SilkReset));
}
#[test]
fn seam_ops_row8_celt_to_silk_resets_only_silk() {
let ops = NormativeTransition::CeltToSilkWithRedundancy.seam_operations();
assert_eq!(ops, &[BoundaryOp::WindowedCrossLap, BoundaryOp::SilkReset]);
assert!(!ops.contains(&BoundaryOp::CeltReset));
assert!(!ops.contains(&BoundaryOp::SilkAndCeltReset));
}
#[test]
fn seam_ops_row9_celt_to_hybrid_uses_dual_reset_marker() {
let ops = NormativeTransition::CeltToHybridWithRedundancy.seam_operations();
assert_eq!(
ops,
&[BoundaryOp::WindowedCrossLap, BoundaryOp::SilkAndCeltReset]
);
}
#[test]
fn carries_redundancy_matches_redundancy_signal() {
for t in [
NormativeTransition::SilkToSilkWithRedundancy,
NormativeTransition::NbOrMbSilkToHybridWithRedundancy,
NormativeTransition::SilkToCeltWithRedundancy,
NormativeTransition::HybridToNbOrMbSilkWithRedundancy,
NormativeTransition::HybridToCeltWithRedundancy,
NormativeTransition::CeltToSilkWithRedundancy,
NormativeTransition::CeltToHybridWithRedundancy,
] {
assert!(t.carries_redundancy(), "{:?} carries R", t);
}
for t in [
NormativeTransition::WbSilkToHybrid,
NormativeTransition::HybridToWbSilk,
] {
assert!(!t.carries_redundancy(), "{:?} does not carry R", t);
}
}
#[test]
fn same_mode_no_bandwidth_change_is_not_normative() {
for (m, bw) in [
(OperatingMode::SilkOnly, Some(SilkBandwidth::Wb)),
(OperatingMode::Hybrid, Some(SilkBandwidth::Wb)),
(OperatingMode::CeltOnly, None),
] {
for red in [true, false] {
let t = classify_normative_transition(m, bw, m, bw, red);
assert_eq!(t, None, "same-mode {:?} should not match Figure 18", m);
}
}
}
#[test]
fn silk_to_silk_same_bandwidth_with_redundancy_is_not_on_figure18() {
for bw in [SilkBandwidth::Nb, SilkBandwidth::Mb, SilkBandwidth::Wb] {
let t = classify_normative_transition(
OperatingMode::SilkOnly,
Some(bw),
OperatingMode::SilkOnly,
Some(bw),
true,
);
assert_eq!(t, None, "SILK {:?}→{:?} +R should not be on row 1", bw, bw);
}
}
#[test]
fn nb_silk_to_hybrid_without_redundancy_is_not_on_figure18() {
let t = classify_normative_transition(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Nb),
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
false,
);
assert_eq!(t, None);
}
#[test]
fn celt_to_silk_without_redundancy_is_not_on_figure18() {
let t = classify_normative_transition(
OperatingMode::CeltOnly,
None,
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
false,
);
assert_eq!(t, None);
}
#[test]
fn fig19_row1_silk_audio_bandwidth_change() {
let t = recommended_non_normative(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Nb),
OperatingMode::SilkOnly,
Some(SilkBandwidth::Mb),
);
assert_eq!(
t,
Some(RecommendedNonNormativeTransition::SilkToSilkAudioBandwidthChange)
);
}
#[test]
fn fig19_row1_silk_same_bandwidth_is_not_on_figure19() {
let t = recommended_non_normative(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
);
assert_eq!(t, None);
}
#[test]
fn fig19_row2_nb_silk_to_hybrid() {
let t = recommended_non_normative(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Nb),
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
);
assert_eq!(
t,
Some(RecommendedNonNormativeTransition::NbOrMbSilkToHybrid)
);
}
#[test]
fn fig19_row2_wb_silk_to_hybrid_is_not_on_figure19() {
let t = recommended_non_normative(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
);
assert_eq!(t, None);
}
#[test]
fn fig19_row3_silk_to_celt_without_redundancy() {
let t = recommended_non_normative(
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
OperatingMode::CeltOnly,
None,
);
assert_eq!(
t,
Some(RecommendedNonNormativeTransition::SilkToCeltWithoutRedundancy)
);
}
#[test]
fn fig19_row4_hybrid_to_nb_silk() {
let t = recommended_non_normative(
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
OperatingMode::SilkOnly,
Some(SilkBandwidth::Nb),
);
assert_eq!(
t,
Some(RecommendedNonNormativeTransition::HybridToNbOrMbSilk)
);
}
#[test]
fn fig19_row4_hybrid_to_wb_silk_is_not_on_figure19() {
let t = recommended_non_normative(
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
);
assert_eq!(t, None);
}
#[test]
fn fig19_row5_hybrid_to_celt_without_redundancy() {
let t = recommended_non_normative(
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
OperatingMode::CeltOnly,
None,
);
assert_eq!(
t,
Some(RecommendedNonNormativeTransition::HybridToCeltWithoutRedundancy)
);
}
#[test]
fn fig19_row6_celt_to_silk_without_redundancy() {
let t = recommended_non_normative(
OperatingMode::CeltOnly,
None,
OperatingMode::SilkOnly,
Some(SilkBandwidth::Wb),
);
assert_eq!(
t,
Some(RecommendedNonNormativeTransition::CeltToSilkWithoutRedundancy)
);
}
#[test]
fn fig19_row7_celt_to_hybrid_without_redundancy() {
let t = recommended_non_normative(
OperatingMode::CeltOnly,
None,
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
);
assert_eq!(
t,
Some(RecommendedNonNormativeTransition::CeltToHybridWithoutRedundancy)
);
}
#[test]
fn fig19_same_mode_celt_to_celt_is_none() {
let t =
recommended_non_normative(OperatingMode::CeltOnly, None, OperatingMode::CeltOnly, None);
assert_eq!(t, None);
}
#[test]
fn fig19_same_mode_hybrid_to_hybrid_is_none() {
let t = recommended_non_normative(
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
OperatingMode::Hybrid,
Some(SilkBandwidth::Wb),
);
assert_eq!(t, None);
}
#[test]
fn fig19_row3_seam_ops_include_plc_celt_reset() {
let ops = RecommendedNonNormativeTransition::SilkToCeltWithoutRedundancy.seam_operations();
assert_eq!(
ops,
&[
BoundaryOp::PacketLossConcealment,
BoundaryOp::WindowedCrossLap,
BoundaryOp::CeltReset,
]
);
}
#[test]
fn fig19_row4_seam_ops_use_overlap_extract_direct_mix() {
let ops = RecommendedNonNormativeTransition::HybridToNbOrMbSilk.seam_operations();
assert_eq!(
ops,
&[
BoundaryOp::CeltOverlapExtract,
BoundaryOp::DirectMix,
BoundaryOp::SilkReset,
]
);
}
#[test]
fn fig19_row7_seam_ops_use_dual_reset_marker() {
let ops =
RecommendedNonNormativeTransition::CeltToHybridWithoutRedundancy.seam_operations();
assert_eq!(
ops,
&[
BoundaryOp::PacketLossConcealment,
BoundaryOp::WindowedCrossLap,
BoundaryOp::SilkAndCeltReset,
]
);
}
#[test]
fn fig18_normative_and_fig19_non_normative_cover_complementary_paths() {
use OperatingMode::*;
let prev_modes = [SilkOnly, Hybrid, CeltOnly];
let next_modes = [SilkOnly, Hybrid, CeltOnly];
let silk_bws = [
None,
Some(SilkBandwidth::Nb),
Some(SilkBandwidth::Mb),
Some(SilkBandwidth::Wb),
];
for prev_m in prev_modes {
for next_m in next_modes {
for prev_bw in silk_bws {
for next_bw in silk_bws {
let n_with_r =
classify_normative_transition(prev_m, prev_bw, next_m, next_bw, true);
let n_no_r =
classify_normative_transition(prev_m, prev_bw, next_m, next_bw, false);
let r = recommended_non_normative(prev_m, prev_bw, next_m, next_bw);
if n_no_r.is_some() {
assert_eq!(
r, None,
"no-R Figure 18 row at {:?}→{:?} bws ({:?}, {:?}) must not also be on Figure 19",
prev_m, next_m, prev_bw, next_bw
);
}
let _ = n_with_r;
}
}
}
}
}
#[test]
fn figure_18_seam_resets_agree_with_section_4_5_2_decisions() {
use crate::mode_transition_reset::{decide_state_resets, CeltResetPlacement};
use OperatingMode::*;
let r = decide_state_resets(SilkOnly, SilkOnly, present());
assert!(!r.silk);
assert_eq!(r.celt, CeltResetPlacement::None);
let r = decide_state_resets(SilkOnly, Hybrid, not_present());
assert!(!r.silk);
assert_eq!(r.celt, CeltResetPlacement::BeforeFrame);
let row3_ops = NormativeTransition::WbSilkToHybrid.seam_operations();
assert!(row3_ops.contains(&BoundaryOp::CeltReset));
let r = decide_state_resets(SilkOnly, CeltOnly, present());
assert!(!r.silk);
assert_eq!(r.celt, CeltResetPlacement::BeforeRedundantOnly);
let row4_ops = NormativeTransition::SilkToCeltWithRedundancy.seam_operations();
assert!(row4_ops.contains(&BoundaryOp::CeltReset));
let r = decide_state_resets(CeltOnly, SilkOnly, present());
assert!(r.silk);
assert_eq!(r.celt, CeltResetPlacement::None);
let row8_ops = NormativeTransition::CeltToSilkWithRedundancy.seam_operations();
assert!(row8_ops.contains(&BoundaryOp::SilkReset));
assert!(!row8_ops.contains(&BoundaryOp::CeltReset));
}
#[test]
fn redundancy_is_present_passthrough() {
assert!(super::redundancy_is_present(present()));
assert!(!super::redundancy_is_present(not_present()));
assert!(!super::redundancy_is_present(invalid()));
}
}