sameer / svg2gcode

Convert vector graphics to g-code for pen plotters, laser engravers, and other CNC machines
https://sameer.github.io/svg2gcode
MIT License
241 stars 48 forks source link

mutably borrowing compiler error #33

Closed martinbaste closed 1 year ago

martinbaste commented 1 year ago

Getting this error when building using this lib as dependency. I fixed it on my code following the compiler's suggestion and seems to work. Here is a PR in case it is useful.

I have no idea about Rust or what this change does but seems to fix the issue. The error:

error[E0308]: mismatched types
   --> /Users/xxx/git/cardplotter/svg2gcode/lib/src/arc.rs:102:39
    |
102 |           self.for_each_monotonic_range(|range| {
    |  ______________------------------------_^
    | |              |
    | |              arguments to this function are incorrect
103 | |             let inner_bezier = self.split_range(range);
104 | |
105 | |             if (inner_bezier.to - inner_bezier.from).square_length() < S::EPSILON {
...   |
135 | |             }
136 | |         });
    | |_________^ expected `&mut _`, found closure
    |
    = note: expected mutable reference `&mut _`
                         found closure `[closure@/Users/xxx/git/cardplotter/svg2gcode/lib/src/arc.rs:102:39: 102:46]`
note: associated function defined here
   --> /Users/xxx/.cargo/registry/src/github.com-1ecc6299db9ec823/lyon_geom-1.0.4/src/cubic_bezier.rs:400:12
    |
400 |     pub fn for_each_monotonic_range<F>(&self, cb: &mut F)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
help: consider mutably borrowing here
    |
102 ~         self.for_each_monotonic_range(&mut |range| {
103 +             let inner_bezier = self.split_range(range);
104 + 
105 +             if (inner_bezier.to - inner_bezier.from).square_length() < S::EPSILON {
106 +                 return;
107 +             } else if inner_bezier.is_linear(tolerance) {
108 +                 acc.push(ArcOrLineSegment::Line(inner_bezier.baseline()));
109 +                 return;
110 +             }
111 + 
112 +             if let Some(svg_arc) = arc_from_endpoints_and_tangents(
113 +                 inner_bezier.from,
114 +                 inner_bezier.derivative(S::ZERO),
115 +                 inner_bezier.to,
116 +                 inner_bezier.derivative(S::ONE),
117 +             )
118 +             .filter(|svg_arc| {
119 +                 let arc = svg_arc.to_arc();
120 +                 let mut max_deviation = S::ZERO;
121 +                 // TODO: find a better way to check tolerance
122 +                 // Ideally: derivative of |f(x) - g(x)| and look at 0 crossings
123 +                 for i in 1..20 {
124 +                     let t = S::from(i).unwrap() / S::from(20).unwrap();
125 +                     max_deviation =
126 +                         max_deviation.max((arc.sample(t) - inner_bezier.sample(t)).length());
127 +                 }
128 +                 max_deviation < tolerance
129 +             }) {
130 +                 acc.push(ArcOrLineSegment::Arc(svg_arc));
131 +             } else {
132 +                 let (left, right) = inner_bezier.split(S::HALF);
133 +                 acc.append(&mut FlattenWithArcs::flattened(&left, tolerance));
134 +                 acc.append(&mut FlattenWithArcs::flattened(&right, tolerance));
135 +             }
136 ~         });
    |

For more information about this error, try `rustc --explain E0308`.
warning: `svg2gcode` (lib) generated 1 warning
error: could not compile `svg2gcode` due to previous error; 1 warning emitted
sameer commented 1 year ago

I'm working on a dependency update that will resolve this, but the web side of things is a lot more complicated than I expected. I appreciate your patience!