chore(router/draw): Make API of 'extend_head' more ergonomic

This commit is contained in:
Ellen Emilia Anna Zscheile 2025-05-20 18:57:36 +02:00
parent 3ae298e4e9
commit 2e84380344
1 changed files with 51 additions and 52 deletions

View File

@ -87,43 +87,44 @@ impl<R: AccessRules> Draw for Layout<R> {
.drawing() .drawing()
.head_into_dot_segment(&head, into, width) .head_into_dot_segment(&head, into, width)
.map_err(Into::<DrawException>::into)?; .map_err(Into::<DrawException>::into)?;
let (head, prev_head_to) = self
.extend_head(recorder, head, tangent.start_point())
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
let layer = head.face().primitive(self.drawing()).layer();
let maybe_net = head.face().primitive(self.drawing()).maybe_net();
match head.face() { let (layer, maybe_net) = {
DotIndex::Fixed(dot) => self let face = head.face().primitive(self.drawing());
.add_lone_loose_seg( (face.layer(), face.maybe_net())
recorder, };
dot,
into, self.extend_head(
LoneLooseSegWeight(GeneralSegWeight { recorder,
width, head,
layer, tangent.start_point(),
maybe_net, |this, recorder| match head.face() {
}), DotIndex::Fixed(dot) => this
) .add_lone_loose_seg(
.map(BandTermsegIndex::Lone), recorder,
DotIndex::Loose(dot) => self dot,
.add_seq_loose_seg( into,
recorder, LoneLooseSegWeight(GeneralSegWeight {
into.into(), width,
dot, layer,
SeqLooseSegWeight(GeneralSegWeight { maybe_net,
width, }),
layer, )
maybe_net, .map(BandTermsegIndex::Lone),
}), DotIndex::Loose(dot) => this
) .add_seq_loose_seg(
.map(BandTermsegIndex::Seq), recorder,
} into.into(),
.map_err(|err| { dot,
// move the head back to where it came from SeqLooseSegWeight(GeneralSegWeight {
self.extend_head(recorder, head, prev_head_to).unwrap(); width,
DrawException::CannotFinishIn(into, err.into()) layer,
}) maybe_net,
}),
)
.map(BandTermsegIndex::Seq),
},
)
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))
} }
#[debug_ensures(ret.is_ok() -> self.drawing().node_count() == old(self.drawing().node_count() + 4))] #[debug_ensures(ret.is_ok() -> self.drawing().node_count() == old(self.drawing().node_count() + 4))]
@ -211,12 +212,13 @@ trait DrawPrivate {
offset: f64, offset: f64,
) -> Result<CaneHead, DrawingException>; ) -> Result<CaneHead, DrawingException>;
fn extend_head( fn extend_head<T, E: From<Infringement>>(
&mut self, &mut self,
recorder: &mut LayoutEdit, recorder: &mut LayoutEdit,
head: Head, head: Head,
to: Point, to: Point,
) -> Result<(Head, Point), Infringement>; then: impl FnOnce(&mut Self, &mut LayoutEdit) -> Result<T, E>,
) -> Result<T, E>;
fn cane( fn cane(
&mut self, &mut self,
@ -246,30 +248,27 @@ impl<R: AccessRules> DrawPrivate for Layout<R> {
width: f64, width: f64,
offset: f64, offset: f64,
) -> Result<CaneHead, DrawingException> { ) -> Result<CaneHead, DrawingException> {
let (head, prev_head_to) = self.extend_head(recorder, head, from)?; self.extend_head(recorder, head, from, |this, recorder| {
self.cane(recorder, head, around, to, sense, width, offset) this.cane(recorder, head, around, to, sense, width, offset)
.inspect_err(|_| { })
// move the head back to where it came from
self.extend_head(recorder, head, prev_head_to).unwrap();
})
} }
#[debug_ensures(self.drawing().node_count() == old(self.drawing().node_count()))] fn extend_head<T, E: From<Infringement>>(
fn extend_head(
&mut self, &mut self,
recorder: &mut LayoutEdit, recorder: &mut LayoutEdit,
head: Head, head: Head,
to: Point, to: Point,
) -> Result<(Head, Point), Infringement> { then: impl FnOnce(&mut Self, &mut LayoutEdit) -> Result<T, E>,
) -> Result<T, E> {
if let Head::Cane(head) = head { if let Head::Cane(head) = head {
let old_pos = self.drawing().geometry().dot_weight(head.face.into()).pos(); let old_pos = self.drawing().geometry().dot_weight(head.face.into()).pos();
self.move_dot(recorder, head.face.into(), to)?; self.move_dot(recorder, head.face.into(), to)?;
Ok((Head::Cane(head), old_pos)) then(self, recorder).inspect_err(|_| {
// move the head back to where it came from
self.move_dot(recorder, head.face.into(), old_pos).unwrap();
})
} else { } else {
Ok(( then(self, recorder)
head,
self.drawing().geometry().dot_weight(head.face()).pos(),
))
} }
} }