mirror of https://codeberg.org/topola/topola.git
chore: trivial fixes of clippy warnings
This commit is contained in:
parent
49d7b3306b
commit
f653a96eb0
|
|
@ -124,13 +124,10 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
options: AutorouterOptions,
|
options: AutorouterOptions,
|
||||||
) -> Result<CompareDetoursExecutionStepper, AutorouterError> {
|
) -> Result<CompareDetoursExecutionStepper, AutorouterError> {
|
||||||
let ratlines = self.selected_ratlines(selection);
|
let ratlines = self.selected_ratlines(selection);
|
||||||
let ratline1 = *ratlines
|
if ratlines.len() < 2 {
|
||||||
.get(0)
|
return Err(AutorouterError::NeedExactlyTwoRatlines);
|
||||||
.ok_or(AutorouterError::NeedExactlyTwoRatlines)?;
|
}
|
||||||
let ratline2 = *ratlines
|
self.compare_detours_ratlines(ratlines[0], ratlines[1], options)
|
||||||
.get(1)
|
|
||||||
.ok_or(AutorouterError::NeedExactlyTwoRatlines)?;
|
|
||||||
self.compare_detours_ratlines(ratline1, ratline2, options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn compare_detours_ratlines(
|
pub(super) fn compare_detours_ratlines(
|
||||||
|
|
|
||||||
|
|
@ -39,47 +39,43 @@ impl ExecutionStepper {
|
||||||
&mut self,
|
&mut self,
|
||||||
invoker: &mut Invoker<M>,
|
invoker: &mut Invoker<M>,
|
||||||
) -> Result<InvokerStatus, InvokerError> {
|
) -> Result<InvokerStatus, InvokerError> {
|
||||||
match self {
|
Ok(match self {
|
||||||
ExecutionStepper::Autoroute(autoroute) => {
|
ExecutionStepper::Autoroute(autoroute) => {
|
||||||
match autoroute.step(&mut invoker.autorouter)? {
|
match autoroute.step(&mut invoker.autorouter)? {
|
||||||
AutorouteStatus::Running => Ok(InvokerStatus::Running),
|
AutorouteStatus::Running => InvokerStatus::Running,
|
||||||
AutorouteStatus::Routed(..) => Ok(InvokerStatus::Running),
|
AutorouteStatus::Routed(..) => InvokerStatus::Running,
|
||||||
AutorouteStatus::Finished => Ok(InvokerStatus::Finished(String::from(
|
AutorouteStatus::Finished => InvokerStatus::Finished(
|
||||||
"finished autorouting",
|
"finished autorouting".to_string(),
|
||||||
))),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExecutionStepper::PlaceVia(place_via) => {
|
ExecutionStepper::PlaceVia(place_via) => {
|
||||||
place_via.doit(&mut invoker.autorouter)?;
|
place_via.doit(&mut invoker.autorouter)?;
|
||||||
Ok(InvokerStatus::Finished(String::from(
|
InvokerStatus::Finished("finished placing via".to_string())
|
||||||
"finished placing via",
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
ExecutionStepper::RemoveBands(remove_bands) => {
|
ExecutionStepper::RemoveBands(remove_bands) => {
|
||||||
remove_bands.doit(&mut invoker.autorouter)?;
|
remove_bands.doit(&mut invoker.autorouter)?;
|
||||||
Ok(InvokerStatus::Finished(String::from(
|
InvokerStatus::Finished("finished removing bands".to_string())
|
||||||
"finished removing bands",
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
ExecutionStepper::CompareDetours(compare_detours) => {
|
ExecutionStepper::CompareDetours(compare_detours) => {
|
||||||
match compare_detours.step(&mut invoker.autorouter)? {
|
match compare_detours.step(&mut invoker.autorouter)? {
|
||||||
CompareDetoursStatus::Running => Ok(InvokerStatus::Running),
|
CompareDetoursStatus::Running => InvokerStatus::Running,
|
||||||
CompareDetoursStatus::Finished(total_length1, total_length2) => {
|
CompareDetoursStatus::Finished(total_length1, total_length2) => {
|
||||||
Ok(InvokerStatus::Finished(String::from(format!(
|
InvokerStatus::Finished(format!(
|
||||||
"total detour lengths are {} and {}",
|
"total detour lengths are {} and {}",
|
||||||
total_length1, total_length2
|
total_length1, total_length2
|
||||||
))))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExecutionStepper::MeasureLength(measure_length) => {
|
ExecutionStepper::MeasureLength(measure_length) => {
|
||||||
let length = measure_length.doit(&mut invoker.autorouter)?;
|
let length = measure_length.doit(&mut invoker.autorouter)?;
|
||||||
Ok(InvokerStatus::Finished(format!(
|
InvokerStatus::Finished(format!(
|
||||||
"Total length of selected bands: {}",
|
"Total length of selected bands: {}",
|
||||||
length
|
length
|
||||||
)))
|
))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ pub enum HistoryError {
|
||||||
NoNextCommand,
|
NoNextCommand,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
pub struct History {
|
pub struct History {
|
||||||
done: Vec<Command>,
|
done: Vec<Command>,
|
||||||
undone: Vec<Command>,
|
undone: Vec<Command>,
|
||||||
|
|
@ -19,10 +19,7 @@ pub struct History {
|
||||||
|
|
||||||
impl History {
|
impl History {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
done: vec![],
|
|
||||||
undone: vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destruct(self) -> (Vec<Command>, Vec<Command>) {
|
pub fn destruct(self) -> (Vec<Command>, Vec<Command>) {
|
||||||
|
|
|
||||||
|
|
@ -84,52 +84,36 @@ impl Ratsnest {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut triangulations = HashMap::new();
|
let mut triangulations = HashMap::new();
|
||||||
|
let node_bound = layout.drawing().geometry().graph().node_bound();
|
||||||
|
|
||||||
for layer in 0..layout.drawing().layer_count() {
|
for layer in 0..layout.drawing().layer_count() {
|
||||||
for node in layout.drawing().layer_primitive_nodes(layer) {
|
let mut handle_rvw = |maybe_net: Option<usize>, vertex: RatvertexIndex, pos: Point| {
|
||||||
match node {
|
if let Some(net) = maybe_net {
|
||||||
PrimitiveIndex::FixedDot(dot) => {
|
triangulations.entry((layer, net))
|
||||||
if layout.polys(dot).next().is_none() {
|
.or_insert_with(|| Triangulation::new(node_bound))
|
||||||
if let Some(net) = layout.drawing().primitive(dot).maybe_net() {
|
.add_vertex(RatvertexWeight { vertex, pos })?;
|
||||||
if !triangulations.contains_key(&(layer, net)) {
|
|
||||||
triangulations.insert(
|
|
||||||
(layer, net),
|
|
||||||
Triangulation::new(
|
|
||||||
layout.drawing().geometry().graph().node_bound(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
triangulations.get_mut(&(layer, net)).unwrap().add_vertex(
|
for node in layout.drawing().layer_primitive_nodes(layer) {
|
||||||
RatvertexWeight {
|
if let PrimitiveIndex::FixedDot(dot) = node {
|
||||||
vertex: RatvertexIndex::FixedDot(dot),
|
if layout.polys(dot).next().is_none() {
|
||||||
pos: node.primitive(layout.drawing()).shape().center(),
|
handle_rvw(
|
||||||
},
|
layout.drawing().primitive(dot).maybe_net(),
|
||||||
|
RatvertexIndex::FixedDot(dot),
|
||||||
|
node.primitive(layout.drawing()).shape().center(),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for poly in layout.layer_poly_nodes(layer) {
|
for poly in layout.layer_poly_nodes(layer) {
|
||||||
if let Some(net) = layout.drawing().compound_weight(poly.into()).maybe_net() {
|
handle_rvw(
|
||||||
if !triangulations.contains_key(&(layer, net)) {
|
layout.drawing().compound_weight(poly.into()).maybe_net(),
|
||||||
triangulations.insert(
|
RatvertexIndex::Poly(poly),
|
||||||
(layer, net),
|
layout.poly(poly).shape().center(),
|
||||||
Triangulation::new(layout.drawing().geometry().graph().node_bound()),
|
)?;
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
triangulations
|
|
||||||
.get_mut(&(layer, net))
|
|
||||||
.unwrap()
|
|
||||||
.add_vertex(RatvertexWeight {
|
|
||||||
vertex: RatvertexIndex::Poly(poly),
|
|
||||||
pos: layout.poly(poly).shape().center(),
|
|
||||||
})?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,14 @@ pub struct PinSelector {
|
||||||
pub layer: String,
|
pub layer: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
pub struct PinSelection {
|
pub struct PinSelection {
|
||||||
selectors: HashSet<PinSelector>,
|
selectors: HashSet<PinSelector>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PinSelection {
|
impl PinSelection {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
selectors: HashSet::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_select_layer(board: &Board<impl AccessMesadata>, layer: usize) -> Self {
|
pub fn new_select_layer(board: &Board<impl AccessMesadata>, layer: usize) -> Self {
|
||||||
|
|
@ -100,16 +98,14 @@ pub struct BandSelector {
|
||||||
pub band: BandName,
|
pub band: BandName,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
pub struct BandSelection {
|
pub struct BandSelection {
|
||||||
selectors: HashSet<BandSelector>,
|
selectors: HashSet<BandSelector>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BandSelection {
|
impl BandSelection {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
selectors: HashSet::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_selector(
|
fn node_selector(
|
||||||
|
|
@ -141,7 +137,7 @@ impl BandSelection {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deselect(&mut self, selector: &BandSelector) {
|
fn deselect(&mut self, selector: &BandSelector) {
|
||||||
self.selectors.remove(&selector);
|
self.selectors.remove(selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains_node(&self, board: &Board<impl AccessMesadata>, node: NodeIndex) -> bool {
|
pub fn contains_node(&self, board: &Board<impl AccessMesadata>, node: NodeIndex) -> bool {
|
||||||
|
|
@ -154,7 +150,7 @@ impl BandSelection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
pub struct Selection {
|
pub struct Selection {
|
||||||
pub pin_selection: PinSelection,
|
pub pin_selection: PinSelection,
|
||||||
pub band_selection: BandSelection,
|
pub band_selection: BandSelection,
|
||||||
|
|
@ -162,10 +158,7 @@ pub struct Selection {
|
||||||
|
|
||||||
impl Selection {
|
impl Selection {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
pin_selection: PinSelection::new(),
|
|
||||||
band_selection: BandSelection::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_at_node(&mut self, board: &Board<impl AccessMesadata>, node: NodeIndex) {
|
pub fn toggle_at_node(&mut self, board: &Board<impl AccessMesadata>, node: NodeIndex) {
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ impl<'a, CW: Copy, R: AccessRules> Collect<'a, CW, R> {
|
||||||
let mut gear = bend;
|
let mut gear = bend;
|
||||||
|
|
||||||
while let Some(outer) = self.drawing.primitive(gear).outer() {
|
while let Some(outer) = self.drawing.primitive(gear).outer() {
|
||||||
v.append(&mut self.bend_bow(outer.into()));
|
v.append(&mut self.bend_bow(outer));
|
||||||
gear = outer;
|
gear = outer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -357,7 +357,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
GeometryLabel::Core
|
GeometryLabel::Core
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|ni| FixedDotIndex::new(ni))
|
.map(FixedDotIndex::new)
|
||||||
.collect::<Vec<FixedDotIndex>>()
|
.collect::<Vec<FixedDotIndex>>()
|
||||||
.first()
|
.first()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -418,7 +418,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
if let Some(outer) = self.primitive(cane.bend).outer() {
|
if let Some(outer) = self.primitive(cane.bend).outer() {
|
||||||
self.update_this_and_outward_bows(outer).map_err(|err| {
|
self.update_this_and_outward_bows(outer).map_err(|err| {
|
||||||
let joint = self.primitive(cane.bend).other_joint(cane.dot);
|
let joint = self.primitive(cane.bend).other_joint(cane.dot);
|
||||||
self.remove_cane(&cane, joint.into());
|
self.remove_cane(&cane, joint);
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
@ -426,12 +426,12 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
// Segs must not cross.
|
// Segs must not cross.
|
||||||
if let Some(collision) = self.detect_collision(cane.seg.into()) {
|
if let Some(collision) = self.detect_collision(cane.seg.into()) {
|
||||||
let joint = self.primitive(cane.bend).other_joint(cane.dot);
|
let joint = self.primitive(cane.bend).other_joint(cane.dot);
|
||||||
self.remove_cane(&cane, joint.into());
|
self.remove_cane(&cane, joint);
|
||||||
return Err(collision.into());
|
Err(collision.into())
|
||||||
}
|
} else {
|
||||||
|
|
||||||
Ok(cane)
|
Ok(cane)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||||
|
|
@ -453,7 +453,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
if let Some(inner) = rail_primitive.inner() {
|
if let Some(inner) = rail_primitive.inner() {
|
||||||
let from = guide
|
let from = guide
|
||||||
.head_around_bend_segment(
|
.head_around_bend_segment(
|
||||||
&from_head.into(),
|
&from_head,
|
||||||
inner.into(),
|
inner.into(),
|
||||||
true,
|
true,
|
||||||
self.primitive(rail).width(),
|
self.primitive(rail).width(),
|
||||||
|
|
@ -461,14 +461,14 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
.end_point();
|
.end_point();
|
||||||
let to = guide
|
let to = guide
|
||||||
.head_around_bend_segment(
|
.head_around_bend_segment(
|
||||||
&to_head.into(),
|
&to_head,
|
||||||
inner.into(),
|
inner.into(),
|
||||||
false,
|
false,
|
||||||
self.primitive(rail).width(),
|
self.primitive(rail).width(),
|
||||||
)?
|
)?
|
||||||
.end_point();
|
.end_point();
|
||||||
let offset = guide.head_around_bend_offset(
|
let offset = guide.head_around_bend_offset(
|
||||||
&from_head.into(),
|
&from_head,
|
||||||
inner.into(),
|
inner.into(),
|
||||||
self.primitive(rail).width(),
|
self.primitive(rail).width(),
|
||||||
);
|
);
|
||||||
|
|
@ -495,7 +495,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
let core = rail_primitive.core();
|
let core = rail_primitive.core();
|
||||||
let from = guide
|
let from = guide
|
||||||
.head_around_dot_segment(
|
.head_around_dot_segment(
|
||||||
&from_head.into(),
|
&from_head,
|
||||||
core.into(),
|
core.into(),
|
||||||
true,
|
true,
|
||||||
self.primitive(rail).width(),
|
self.primitive(rail).width(),
|
||||||
|
|
@ -503,14 +503,14 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
.end_point();
|
.end_point();
|
||||||
let to = guide
|
let to = guide
|
||||||
.head_around_dot_segment(
|
.head_around_dot_segment(
|
||||||
&to_head.into(),
|
&to_head,
|
||||||
core.into(),
|
core.into(),
|
||||||
false,
|
false,
|
||||||
self.primitive(rail).width(),
|
self.primitive(rail).width(),
|
||||||
)?
|
)?
|
||||||
.end_point();
|
.end_point();
|
||||||
let offset = guide.head_around_dot_offset(
|
let offset = guide.head_around_dot_offset(
|
||||||
&from_head.into(),
|
&from_head,
|
||||||
core.into(),
|
core.into(),
|
||||||
self.primitive(rail).width(),
|
self.primitive(rail).width(),
|
||||||
);
|
);
|
||||||
|
|
@ -659,7 +659,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
self.geometry_with_rtree.move_dot(dot, to);
|
self.geometry_with_rtree.move_dot(dot, to);
|
||||||
|
|
||||||
for limb in dot.primitive(self).limbs() {
|
for limb in dot.primitive(self).limbs() {
|
||||||
if let Some(infringement) = self.detect_infringement_except(limb.into(), infringables) {
|
if let Some(infringement) = self.detect_infringement_except(limb, infringables) {
|
||||||
// Restore original state.
|
// Restore original state.
|
||||||
self.geometry_with_rtree.move_dot(dot, old_pos);
|
self.geometry_with_rtree.move_dot(dot, old_pos);
|
||||||
return Err(infringement);
|
return Err(infringement);
|
||||||
|
|
@ -713,10 +713,8 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(|primitive_node| !self.are_connectable(node, *primitive_node))
|
.filter(|primitive_node| !self.are_connectable(node, *primitive_node))
|
||||||
.filter(|primitive_node| shape.intersects(&primitive_node.primitive(self).shape()))
|
.find(|primitive_node| shape.intersects(&primitive_node.primitive(self).shape()))
|
||||||
.map(|primitive_node| primitive_node)
|
.map(|collidee| Collision(shape, collidee))
|
||||||
.next()
|
|
||||||
.and_then(|collidee| Some(Collision(shape, collidee)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -784,7 +782,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(|primitive_node| {
|
.filter(|primitive_node| {
|
||||||
maybe_except.is_some_and(|except| !except.contains(&primitive_node))
|
maybe_except.is_some_and(|except| !except.contains(primitive_node))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -796,7 +794,7 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
let limiting_shape = node.primitive(self).shape().inflate(
|
let limiting_shape = node.primitive(self).shape().inflate(
|
||||||
node.primitive(self)
|
node.primitive(self)
|
||||||
.maybe_net()
|
.maybe_net()
|
||||||
.and_then(|net| Some(self.rules.largest_clearance(Some(net))))
|
.map(|net| self.rules.largest_clearance(Some(net)))
|
||||||
.unwrap_or(0.0),
|
.unwrap_or(0.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -929,13 +927,12 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
fn test_if_looses_dont_infringe_each_other(&self) -> bool {
|
fn test_if_looses_dont_infringe_each_other(&self) -> bool {
|
||||||
!self
|
!self
|
||||||
.primitive_nodes()
|
.primitive_nodes()
|
||||||
.filter(|node| match node {
|
.filter(|node| matches!(node,
|
||||||
PrimitiveIndex::LooseDot(..)
|
PrimitiveIndex::LooseDot(..)
|
||||||
| PrimitiveIndex::LoneLooseSeg(..)
|
| PrimitiveIndex::LoneLooseSeg(..)
|
||||||
| PrimitiveIndex::SeqLooseSeg(..)
|
| PrimitiveIndex::SeqLooseSeg(..)
|
||||||
| PrimitiveIndex::LooseBend(..) => true,
|
| PrimitiveIndex::LooseBend(..)
|
||||||
_ => false,
|
))
|
||||||
})
|
|
||||||
.any(|node| {
|
.any(|node| {
|
||||||
self.find_infringement(
|
self.find_infringement(
|
||||||
node,
|
node,
|
||||||
|
|
@ -947,13 +944,12 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(|primitive_node| match primitive_node {
|
.filter(|primitive_node| matches!(primitive_node,
|
||||||
PrimitiveIndex::LooseDot(..)
|
PrimitiveIndex::LooseDot(..)
|
||||||
| PrimitiveIndex::LoneLooseSeg(..)
|
| PrimitiveIndex::LoneLooseSeg(..)
|
||||||
| PrimitiveIndex::SeqLooseSeg(..)
|
| PrimitiveIndex::SeqLooseSeg(..)
|
||||||
| PrimitiveIndex::LooseBend(..) => true,
|
| PrimitiveIndex::LooseBend(..)
|
||||||
_ => false,
|
)),
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
.is_some()
|
.is_some()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,7 @@ impl<'a, W, CW: Copy, R: AccessRules> GenericPrimitive<'a, W, CW, R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primitive<WW>(&self, index: GenericIndex<WW>) -> GenericPrimitive<WW, CW, R> {
|
fn primitive<WW>(&self, index: GenericIndex<WW>) -> GenericPrimitive<WW, CW, R> {
|
||||||
GenericPrimitive::new(index, &self.drawing)
|
GenericPrimitive::new(index, self.drawing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -379,7 +379,7 @@ impl<'a, CW: Copy, R: AccessRules> GetJoints<DotIndex, LooseDotIndex> for SeqLoo
|
||||||
if let DotWeight::Fixed(..) = self.drawing.geometry().dot_weight(joints.0) {
|
if let DotWeight::Fixed(..) = self.drawing.geometry().dot_weight(joints.0) {
|
||||||
(
|
(
|
||||||
FixedDotIndex::new(joints.0.petgraph_index()).into(),
|
FixedDotIndex::new(joints.0.petgraph_index()).into(),
|
||||||
LooseDotIndex::new(joints.1.petgraph_index()).into(),
|
LooseDotIndex::new(joints.1.petgraph_index()),
|
||||||
)
|
)
|
||||||
} else if let DotWeight::Fixed(..) = self.drawing.geometry().dot_weight(joints.1) {
|
} else if let DotWeight::Fixed(..) = self.drawing.geometry().dot_weight(joints.1) {
|
||||||
(
|
(
|
||||||
|
|
@ -389,7 +389,7 @@ impl<'a, CW: Copy, R: AccessRules> GetJoints<DotIndex, LooseDotIndex> for SeqLoo
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
LooseDotIndex::new(joints.0.petgraph_index()).into(),
|
LooseDotIndex::new(joints.0.petgraph_index()).into(),
|
||||||
LooseDotIndex::new(joints.1.petgraph_index()).into(),
|
LooseDotIndex::new(joints.1.petgraph_index()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -221,8 +221,7 @@ impl<
|
||||||
if let Some(old_inner_edge) = self
|
if let Some(old_inner_edge) = self
|
||||||
.graph
|
.graph
|
||||||
.edges_directed(bend.petgraph_index(), Incoming)
|
.edges_directed(bend.petgraph_index(), Incoming)
|
||||||
.filter(|edge| *edge.weight() == GeometryLabel::Outer)
|
.find(|edge| *edge.weight() == GeometryLabel::Outer)
|
||||||
.next()
|
|
||||||
{
|
{
|
||||||
self.graph.remove_edge(old_inner_edge.id());
|
self.graph.remove_edge(old_inner_edge.id());
|
||||||
}
|
}
|
||||||
|
|
@ -274,10 +273,7 @@ impl<
|
||||||
let mut rail = bend;
|
let mut rail = bend;
|
||||||
|
|
||||||
while let Some(inner) = self.inner(rail) {
|
while let Some(inner) = self.inner(rail) {
|
||||||
let weight: BW = self
|
let weight: BW = self.bend_weight(inner);
|
||||||
.bend_weight(inner)
|
|
||||||
.try_into()
|
|
||||||
.unwrap_or_else(|_| unreachable!());
|
|
||||||
r += weight.width() + weight.offset();
|
r += weight.width() + weight.offset();
|
||||||
rail = inner;
|
rail = inner;
|
||||||
}
|
}
|
||||||
|
|
@ -441,8 +437,6 @@ impl<
|
||||||
.map(|ni| {
|
.map(|ni| {
|
||||||
self.primitive_weight(ni)
|
self.primitive_weight(ni)
|
||||||
.retag(ni)
|
.retag(ni)
|
||||||
.try_into()
|
|
||||||
.unwrap_or_else(|_| unreachable!())
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -485,12 +479,7 @@ impl<
|
||||||
GeometryLabel::Compound
|
GeometryLabel::Compound
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|ni| {
|
.map(|ni| self.primitive_weight(ni).retag(ni))
|
||||||
self.primitive_weight(ni)
|
|
||||||
.retag(ni)
|
|
||||||
.try_into()
|
|
||||||
.unwrap_or_else(|_| unreachable!())
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn graph(&self) -> &StableDiGraph<GenericNode<PW, CW>, GeometryLabel, usize> {
|
pub fn graph(&self) -> &StableDiGraph<GenericNode<PW, CW>, GeometryLabel, usize> {
|
||||||
|
|
|
||||||
|
|
@ -37,13 +37,12 @@ impl<'a, R: AccessRules> Poly<'a, R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_apex(&self, dot: FixedDotIndex) -> bool {
|
fn is_apex(&self, dot: FixedDotIndex) -> bool {
|
||||||
self.layout
|
!self.layout
|
||||||
.drawing()
|
.drawing()
|
||||||
.primitive(dot)
|
.primitive(dot)
|
||||||
.segs()
|
.segs()
|
||||||
.iter()
|
.iter()
|
||||||
.find(|seg| matches!(seg, SegIndex::Fixed(..)))
|
.any(|seg| matches!(seg, SegIndex::Fixed(..)))
|
||||||
.is_none()
|
|
||||||
&& self.layout.drawing().primitive(dot).bends().is_empty()
|
&& self.layout.drawing().primitive(dot).bends().is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +83,7 @@ impl<'a, R: AccessRules> MakePolyShape for Poly<'a, R> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.is_apex(dot) {
|
if self.is_apex(dot) {
|
||||||
return None;
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(
|
Some(
|
||||||
self.layout
|
self.layout
|
||||||
|
|
@ -164,13 +163,13 @@ pub struct PourPolyWeight {
|
||||||
pub maybe_net: Option<usize>,
|
pub maybe_net: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GetLayer for PourPolyWeight {
|
impl GetLayer for PourPolyWeight {
|
||||||
fn layer(&self) -> usize {
|
fn layer(&self) -> usize {
|
||||||
self.layer
|
self.layer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GetMaybeNet for PourPolyWeight {
|
impl GetMaybeNet for PourPolyWeight {
|
||||||
fn maybe_net(&self) -> Option<usize> {
|
fn maybe_net(&self) -> Option<usize> {
|
||||||
self.maybe_net
|
self.maybe_net
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
src/math.rs
18
src/math.rs
|
|
@ -81,13 +81,12 @@ fn _tangents(circle1: Circle, circle2: Circle) -> Result<[CanonicalLine; 4], ()>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cast_point_to_canonical_line(pt: Point, line: CanonicalLine) -> Point {
|
fn cast_point_to_canonical_line(pt: Point, line: CanonicalLine) -> Point {
|
||||||
return (
|
(
|
||||||
(line.b * (line.b * pt.x() - line.a * pt.y()) - line.a * line.c)
|
(line.b * (line.b * pt.x() - line.a * pt.y()) - line.a * line.c)
|
||||||
/ (line.a * line.a + line.b * line.b),
|
/ (line.a * line.a + line.b * line.b),
|
||||||
(line.a * (-line.b * pt.x() + line.a * pt.y()) - line.b * line.c)
|
(line.a * (-line.b * pt.x() + line.a * pt.y()) - line.b * line.c)
|
||||||
/ (line.a * line.a + line.b * line.b),
|
/ (line.a * line.a + line.b * line.b),
|
||||||
)
|
).into()
|
||||||
.into();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tangent_point_pairs(
|
fn tangent_point_pairs(
|
||||||
|
|
@ -193,6 +192,7 @@ pub fn intersect_circle_segment(circle: &Circle, segment: &Line) -> Vec<Point> {
|
||||||
let from = segment.start_point();
|
let from = segment.start_point();
|
||||||
let to = segment.end_point();
|
let to = segment.end_point();
|
||||||
let epsilon = 1e-9;
|
let epsilon = 1e-9;
|
||||||
|
let interval01 = 0.0..=1.0;
|
||||||
|
|
||||||
let a = delta.dot(delta);
|
let a = delta.dot(delta);
|
||||||
let b =
|
let b =
|
||||||
|
|
@ -209,24 +209,24 @@ pub fn intersect_circle_segment(circle: &Circle, segment: &Line) -> Vec<Point> {
|
||||||
if discriminant == 0.0 {
|
if discriminant == 0.0 {
|
||||||
let u = -b / (2.0 * a);
|
let u = -b / (2.0 * a);
|
||||||
|
|
||||||
if u >= 0.0 && u <= 1.0 {
|
return if interval01.contains(&u) {
|
||||||
return [from + (to - from) * -b / (2.0 * a)].into();
|
vec![from + (to - from) * -b / (2.0 * a)]
|
||||||
} else {
|
} else {
|
||||||
return [].into();
|
vec![]
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut v = vec![];
|
let mut v = vec![];
|
||||||
|
|
||||||
let u1 = (-b + discriminant.sqrt()) / (2.0 * a);
|
let u1 = (-b + discriminant.sqrt()) / (2.0 * a);
|
||||||
|
|
||||||
if u1 >= 0.0 && u1 <= 1.0 {
|
if interval01.contains(&u1) {
|
||||||
v.push(from + (to - from) * u1);
|
v.push(from + (to - from) * u1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let u2 = (-b - discriminant.sqrt()) / (2.0 * a);
|
let u2 = (-b - discriminant.sqrt()) / (2.0 * a);
|
||||||
|
|
||||||
if u2 >= 0.0 && u2 <= 1.0 {
|
if interval01.contains(&u2) {
|
||||||
v.push(from + (to - from) * u2);
|
v.push(from + (to - from) * u2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ where
|
||||||
graph: &'a G,
|
graph: &'a G,
|
||||||
edge: <&'a G as IntoEdgeReferences>::EdgeRef,
|
edge: <&'a G as IntoEdgeReferences>::EdgeRef,
|
||||||
) -> Option<K>;
|
) -> Option<K>;
|
||||||
fn remove_probe<'a>(&mut self, graph: &'a G);
|
fn remove_probe(&mut self, graph: &G);
|
||||||
fn estimate_cost(&mut self, graph: &G, node: G::NodeId) -> K;
|
fn estimate_cost(&mut self, graph: &G, node: G::NodeId) -> K;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,7 +198,7 @@ where
|
||||||
let zero_score = K::default();
|
let zero_score = K::default();
|
||||||
this.scores.insert(start, zero_score);
|
this.scores.insert(start, zero_score);
|
||||||
this.visit_next.push(MinScored(
|
this.visit_next.push(MinScored(
|
||||||
strategy.estimate_cost(&&this.graph, start),
|
strategy.estimate_cost(&this.graph, start),
|
||||||
start,
|
start,
|
||||||
));
|
));
|
||||||
this
|
this
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ impl<'a, R: AccessRules> Draw<'a, R> {
|
||||||
self.layout
|
self.layout
|
||||||
.add_lone_loose_seg(
|
.add_lone_loose_seg(
|
||||||
dot,
|
dot,
|
||||||
into.into(),
|
into,
|
||||||
LoneLooseSegWeight {
|
LoneLooseSegWeight {
|
||||||
width,
|
width,
|
||||||
layer,
|
layer,
|
||||||
|
|
@ -130,10 +130,10 @@ impl<'a, R: AccessRules> Draw<'a, R> {
|
||||||
) -> Result<CaneHead, DrawException> {
|
) -> Result<CaneHead, DrawException> {
|
||||||
let tangent = self
|
let tangent = self
|
||||||
.guide()
|
.guide()
|
||||||
.head_around_bend_segment(&head, around.into(), cw, width)?;
|
.head_around_bend_segment(&head, around, cw, width)?;
|
||||||
let offset = self
|
let offset = self
|
||||||
.guide()
|
.guide()
|
||||||
.head_around_bend_offset(&head, around.into(), width);
|
.head_around_bend_offset(&head, around, width);
|
||||||
|
|
||||||
self.cane_around(
|
self.cane_around(
|
||||||
head,
|
head,
|
||||||
|
|
|
||||||
|
|
@ -367,7 +367,7 @@ impl<'a> IntoNeighbors for &'a Navmesh {
|
||||||
Box::new(
|
Box::new(
|
||||||
self.graph
|
self.graph
|
||||||
.neighbors(vertex.petgraph_index())
|
.neighbors(vertex.petgraph_index())
|
||||||
.map(|ni| NavvertexIndex(ni)),
|
.map(NavvertexIndex),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -109,11 +109,11 @@ impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, BandTermsegIndex>
|
||||||
let width = self.trace.width;
|
let width = self.trace.width;
|
||||||
|
|
||||||
self.tracer
|
self.tracer
|
||||||
.rework_path(navmesh, &mut self.trace, &new_path[..], width)
|
.rework_path(navmesh, self.trace, &new_path[..], width)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
self.tracer
|
self.tracer
|
||||||
.finish(navmesh, &mut self.trace, self.target, width)
|
.finish(navmesh, self.trace, self.target, width)
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,11 +205,11 @@ impl<'a, R: AccessRules> Router<'a, R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout_mut(&mut self) -> &mut Layout<R> {
|
pub fn layout_mut(&mut self) -> &mut Layout<R> {
|
||||||
&mut self.layout
|
self.layout
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout(&self) -> &Layout<R> {
|
pub fn layout(&self) -> &Layout<R> {
|
||||||
&self.layout
|
self.layout
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn options(&self) -> RouterOptions {
|
pub fn options(&self) -> RouterOptions {
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ impl TraceStepper {
|
||||||
cw: bool,
|
cw: bool,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<CaneHead, TracerException> {
|
) -> Result<CaneHead, TracerException> {
|
||||||
Ok(Draw::new(tracer.layout).cane_around_dot(head, around.into(), cw, width)?)
|
Ok(Draw::new(tracer.layout).cane_around_dot(head, around, cw, width)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_around_loose_bend(
|
fn wrap_around_loose_bend(
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ impl<'a, R: AccessRules> Tracer<'a, R> {
|
||||||
width,
|
width,
|
||||||
}) {
|
}) {
|
||||||
self.undo_path(trace, i);
|
self.undo_path(trace, i);
|
||||||
return Err(err.into());
|
return Err(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -193,12 +193,12 @@ impl SpecctraDesign {
|
||||||
)));
|
)));
|
||||||
|
|
||||||
// mapping of pin -> net prepared for adding pins
|
// mapping of pin -> net prepared for adding pins
|
||||||
let pin_nets = HashMap::<String, usize>::from_iter(
|
let pin_nets = self.pcb
|
||||||
self.pcb
|
|
||||||
.network
|
.network
|
||||||
.nets
|
.nets
|
||||||
.iter()
|
.iter()
|
||||||
.map(|net_pin_assignments| {
|
// flatten the nested iters into a single stream of tuples
|
||||||
|
.flat_map(|net_pin_assignments| {
|
||||||
// resolve the id so we don't work with strings
|
// resolve the id so we don't work with strings
|
||||||
let net = board
|
let net = board
|
||||||
.layout()
|
.layout()
|
||||||
|
|
@ -215,9 +215,7 @@ impl SpecctraDesign {
|
||||||
.iter()
|
.iter()
|
||||||
.map(move |pinname| (pinname.clone(), net))
|
.map(move |pinname| (pinname.clone(), net))
|
||||||
})
|
})
|
||||||
// flatten the nested iters into a single stream of tuples
|
.collect::<HashMap<String, usize>>();
|
||||||
.flatten(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// add pins from components
|
// add pins from components
|
||||||
for component in &self.pcb.placement.components {
|
for component in &self.pcb.placement.components {
|
||||||
|
|
@ -416,7 +414,7 @@ impl SpecctraDesign {
|
||||||
|
|
||||||
fn layer(
|
fn layer(
|
||||||
board: &Board<SpecctraMesadata>,
|
board: &Board<SpecctraMesadata>,
|
||||||
layers: &Vec<Layer>,
|
layers: &[Layer],
|
||||||
layername: &str,
|
layername: &str,
|
||||||
front: bool,
|
front: bool,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
|
|
@ -571,7 +569,7 @@ impl SpecctraDesign {
|
||||||
board: &mut Board<SpecctraMesadata>,
|
board: &mut Board<SpecctraMesadata>,
|
||||||
place: PointWithRotation,
|
place: PointWithRotation,
|
||||||
pin: PointWithRotation,
|
pin: PointWithRotation,
|
||||||
coords: &Vec<structure::Point>,
|
coords: &[structure::Point],
|
||||||
width: f64,
|
width: f64,
|
||||||
layer: usize,
|
layer: usize,
|
||||||
net: usize,
|
net: usize,
|
||||||
|
|
@ -632,7 +630,7 @@ impl SpecctraDesign {
|
||||||
board: &mut Board<SpecctraMesadata>,
|
board: &mut Board<SpecctraMesadata>,
|
||||||
place: PointWithRotation,
|
place: PointWithRotation,
|
||||||
pin: PointWithRotation,
|
pin: PointWithRotation,
|
||||||
coords: &Vec<structure::Point>,
|
coords: &[structure::Point],
|
||||||
width: f64,
|
width: f64,
|
||||||
layer: usize,
|
layer: usize,
|
||||||
net: usize,
|
net: usize,
|
||||||
|
|
@ -667,7 +665,7 @@ impl SpecctraDesign {
|
||||||
let index = board.add_poly_fixed_dot_infringably(
|
let index = board.add_poly_fixed_dot_infringably(
|
||||||
FixedDotWeight {
|
FixedDotWeight {
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: Self::pos(place, pin, coord.x, coord.y).into(),
|
pos: Self::pos(place, pin, coord.x, coord.y),
|
||||||
r: width / 2.0,
|
r: width / 2.0,
|
||||||
},
|
},
|
||||||
layer,
|
layer,
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ impl<R: std::io::BufRead> ReadDsn<R> for Parser {
|
||||||
|
|
||||||
impl<R: std::io::BufRead> ReadDsn<R> for String {
|
impl<R: std::io::BufRead> ReadDsn<R> for String {
|
||||||
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
||||||
Ok(tokenizer.consume_token()?.expect_leaf()?)
|
tokenizer.consume_token()?.expect_leaf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,51 +109,51 @@ impl<R: std::io::BufRead> ReadDsn<R> for bool {
|
||||||
|
|
||||||
impl<R: std::io::BufRead> ReadDsn<R> for i32 {
|
impl<R: std::io::BufRead> ReadDsn<R> for i32 {
|
||||||
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
||||||
Ok(tokenizer
|
tokenizer
|
||||||
.consume_token()?
|
.consume_token()?
|
||||||
.expect_leaf()?
|
.expect_leaf()?
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|_| tokenizer.add_context(ParseError::Expected("i32")))?)
|
.map_err(|_| tokenizer.add_context(ParseError::Expected("i32")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: std::io::BufRead> ReadDsn<R> for u32 {
|
impl<R: std::io::BufRead> ReadDsn<R> for u32 {
|
||||||
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
||||||
Ok(tokenizer
|
tokenizer
|
||||||
.consume_token()?
|
.consume_token()?
|
||||||
.expect_leaf()?
|
.expect_leaf()?
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|_| tokenizer.add_context(ParseError::Expected("u32")))?)
|
.map_err(|_| tokenizer.add_context(ParseError::Expected("u32")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: std::io::BufRead> ReadDsn<R> for usize {
|
impl<R: std::io::BufRead> ReadDsn<R> for usize {
|
||||||
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
||||||
Ok(tokenizer
|
tokenizer
|
||||||
.consume_token()?
|
.consume_token()?
|
||||||
.expect_leaf()?
|
.expect_leaf()?
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|_| tokenizer.add_context(ParseError::Expected("usize")))?)
|
.map_err(|_| tokenizer.add_context(ParseError::Expected("usize")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: std::io::BufRead> ReadDsn<R> for f32 {
|
impl<R: std::io::BufRead> ReadDsn<R> for f32 {
|
||||||
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
||||||
Ok(tokenizer
|
tokenizer
|
||||||
.consume_token()?
|
.consume_token()?
|
||||||
.expect_leaf()?
|
.expect_leaf()?
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|_| tokenizer.add_context(ParseError::Expected("f32")))?)
|
.map_err(|_| tokenizer.add_context(ParseError::Expected("f32")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: std::io::BufRead> ReadDsn<R> for f64 {
|
impl<R: std::io::BufRead> ReadDsn<R> for f64 {
|
||||||
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
||||||
Ok(tokenizer
|
tokenizer
|
||||||
.consume_token()?
|
.consume_token()?
|
||||||
.expect_leaf()?
|
.expect_leaf()?
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|_| tokenizer.add_context(ParseError::Expected("f64")))?)
|
.map_err(|_| tokenizer.add_context(ParseError::Expected("f64")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,7 +170,7 @@ pub struct ListTokenizer<R: std::io::BufRead> {
|
||||||
impl<R: std::io::BufRead> ListTokenizer<R> {
|
impl<R: std::io::BufRead> ListTokenizer<R> {
|
||||||
pub fn new(reader: R) -> Self {
|
pub fn new(reader: R) -> Self {
|
||||||
Self {
|
Self {
|
||||||
reader: reader,
|
reader,
|
||||||
peeked_char: None,
|
peeked_char: None,
|
||||||
cached_token: None,
|
cached_token: None,
|
||||||
space_in_quoted: false,
|
space_in_quoted: false,
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ pub struct Library {
|
||||||
|
|
||||||
impl Library {
|
impl Library {
|
||||||
pub fn find_padstack_by_name(&self, name: &str) -> Option<&Padstack> {
|
pub fn find_padstack_by_name(&self, name: &str) -> Option<&Padstack> {
|
||||||
self.padstacks.iter().find(|padstack| &padstack.name == name)
|
self.padstacks.iter().find(|padstack| padstack.name == name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,9 @@ impl<W: io::Write> WriteSes<W> for char {
|
||||||
|
|
||||||
impl<W: io::Write> WriteSes<W> for String {
|
impl<W: io::Write> WriteSes<W> for String {
|
||||||
fn write_dsn(&self, writer: &mut ListWriter<W>) -> Result<(), io::Error> {
|
fn write_dsn(&self, writer: &mut ListWriter<W>) -> Result<(), io::Error> {
|
||||||
let string = if self.len() == 0 {
|
let string = if self.is_empty() {
|
||||||
"\"\"".to_string()
|
"\"\"".to_string()
|
||||||
} else if self.contains(" ")
|
} else if self.contains(|i: char| i == ' ' || i == '(' || i == ')' || i == '\n') {
|
||||||
|| self.contains("(")
|
|
||||||
|| self.contains(")")
|
|
||||||
|| self.contains("\n")
|
|
||||||
{
|
|
||||||
format!("\"{}\"", self)
|
format!("\"{}\"", self)
|
||||||
} else {
|
} else {
|
||||||
self.to_string()
|
self.to_string()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue