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,14 +87,18 @@ 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());
(face.layer(), face.maybe_net())
};
self.extend_head(
recorder,
head,
tangent.start_point(),
|this, recorder| match head.face() {
DotIndex::Fixed(dot) => this
.add_lone_loose_seg( .add_lone_loose_seg(
recorder, recorder,
dot, dot,
@ -106,7 +110,7 @@ impl<R: AccessRules> Draw for Layout<R> {
}), }),
) )
.map(BandTermsegIndex::Lone), .map(BandTermsegIndex::Lone),
DotIndex::Loose(dot) => self DotIndex::Loose(dot) => this
.add_seq_loose_seg( .add_seq_loose_seg(
recorder, recorder,
into.into(), into.into(),
@ -118,12 +122,9 @@ impl<R: AccessRules> Draw for Layout<R> {
}), }),
) )
.map(BandTermsegIndex::Seq), .map(BandTermsegIndex::Seq),
} },
.map_err(|err| { )
// move the head back to where it came from .map_err(|err| DrawException::CannotFinishIn(into, err.into()))
self.extend_head(recorder, head, prev_head_to).unwrap();
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(),
))
} }
} }