use closure instead of iterator

This commit is contained in:
2025-06-04 18:18:18 -07:00
parent 534598ba70
commit 90d13d28ae

@ -540,23 +540,23 @@ impl MapCheck<'_>{
}
}
struct Separated<I>{
iter:I,
struct Separated<F>{
f:F,
separator:&'static str,
}
impl<I> Separated<I>{
fn new(separator:&'static str,iter:I)->Self{
Self{separator,iter}
impl<F> Separated<F>{
fn new(separator:&'static str,f:F)->Self{
Self{separator,f}
}
}
impl<I,D> std::fmt::Display for Separated<I>
impl<F,I,D> std::fmt::Display for Separated<F>
where
D:std::fmt::Display,
I:Clone,
I:Iterator<Item=D>,
I:IntoIterator<Item=D>,
F:Fn()->I,
{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
let mut it=self.iter.clone();
let mut it=(self.f)().into_iter();
if let Some(first)=it.next(){
write!(f,"{first}")?;
for item in it{
@ -661,7 +661,7 @@ impl MapCheck<'_>{
let duplicate_start=match &self.mode_start_counts{
DuplicateCheck(Ok(()))=>CheckSummary::passed("DuplicateStart"),
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
let context=Separated::new(", ",context.iter().map(|(&mode_id,names)|
let context=Separated::new(", ",||context.iter().map(|(&mode_id,names)|
Duplicates::new(ModeElement{zone:Zone::Start,mode_id},names.len())
));
summary_format!("DuplicateStart","Duplicate start zones: {context}",())
@ -674,7 +674,7 @@ impl MapCheck<'_>{
CheckSummary::passed("ExtraFinish")
}else{
let plural=if context.extra.len()==1{"zone"}else{"zones"};
let context=Separated::new(", ",context.extra.iter().map(|(&mode_id,_names)|
let context=Separated::new(", ",||context.extra.iter().map(|(&mode_id,_names)|
ModeElement{zone:Zone::Finish,mode_id}
));
summary_format!("ExtraFinish","No matching start zone for finish {plural}: {context}",())
@ -683,7 +683,7 @@ impl MapCheck<'_>{
CheckSummary::passed("MissingFinish")
}else{
let plural=if context.missing.len()==1{"zone"}else{"zones"};
let context=Separated::new(", ",context.missing.iter().map(|&mode_id|
let context=Separated::new(", ",||context.missing.iter().map(|&mode_id|
ModeElement{zone:Zone::Finish,mode_id}
));
summary_format!("MissingFinish","Missing finish {plural}: {context}",())
@ -697,7 +697,7 @@ impl MapCheck<'_>{
CheckSummary::passed("DanglingAnticheat")
}else{
let plural=if context.extra.len()==1{"zone"}else{"zones"};
let context=Separated::new(", ",context.extra.iter().map(|(&mode_id,_names)|
let context=Separated::new(", ",||context.extra.iter().map(|(&mode_id,_names)|
ModeElement{zone:Zone::Anticheat,mode_id}
));
summary_format!("DanglingAnticheat","No matching start zone for anticheat {plural}: {context}",())
@ -713,14 +713,14 @@ impl MapCheck<'_>{
SetDifferenceCheck(Err(context))=>{
let unique_names:HashSet<_>=context.extra.values().flat_map(|names|names.iter().copied()).collect();
let plural=if unique_names.len()==1{"object"}else{"objects"};
let context=Separated::new(", ",unique_names.iter());
let context=Separated::new(", ",||&unique_names);
summary_format!("DanglingTeleport","No matching Spawn for {plural}: {context}",())
}
};
let duplicate_spawns=match &self.spawn_counts{
DuplicateCheck(Ok(()))=>CheckSummary::passed("DuplicateSpawn"),
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
let context=Separated::new(", ",context.iter().map(|(&stage_id,&names)|
let context=Separated::new(", ",||context.iter().map(|(&stage_id,&names)|
Duplicates::new(StageElement{behaviour:StageElementBehaviour::Spawn,stage_id},names as usize)
));
summary_format!("DuplicateSpawn","Duplicate Spawn: {context}",())
@ -732,7 +732,7 @@ impl MapCheck<'_>{
if context.extra.is_empty(){
CheckSummary::passed("ExtraWormholeIn")
}else{
let context=Separated::new(", ",context.extra.iter().map(|(&wormhole_id,_names)|
let context=Separated::new(", ",||context.extra.iter().map(|(&wormhole_id,_names)|
WormholeElement{behaviour:WormholeBehaviour::In,wormhole_id}
));
summary_format!("ExtraWormholeIn","WormholeIn with no matching WormholeOut: {context}",())
@ -742,7 +742,7 @@ impl MapCheck<'_>{
}else{
// This counts WormholeIn objects, but
// flipped logic is easier to understand
let context=Separated::new(", ",context.missing.iter().map(|&wormhole_id|
let context=Separated::new(", ",||context.missing.iter().map(|&wormhole_id|
WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id}
));
summary_format!("MissingWormholeIn","WormholeOut with no matching WormholeIn: {context}",())
@ -752,7 +752,7 @@ impl MapCheck<'_>{
let duplicate_wormhole_out=match &self.wormhole_out_counts{
DuplicateCheck(Ok(()))=>CheckSummary::passed("DuplicateWormholeOut"),
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
let context=Separated::new(", ",context.iter().map(|(&wormhole_id,&names)|
let context=Separated::new(", ",||context.iter().map(|(&wormhole_id,&names)|
Duplicates::new(WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id},names as usize)
));
summary_format!("DuplicateWormholeOut","Duplicate WormholeOut: {context}",())
@ -785,7 +785,7 @@ struct MapCheckList{
}
impl MapCheckList{
fn summary(&self)->String{
Separated::new("; ",self.checks.iter().filter_map(|check|
Separated::new("; ",||self.checks.iter().filter_map(|check|
(!check.passed).then_some(check.summary.as_str())
)).to_string()
}