idf_parser/point.rs
1use crate::primitives::ws;
2use crate::ws_separated;
3
4use nom::character::complete::u32;
5use nom::number::complete::float;
6use nom::{IResult, Parser};
7
8/// Represents a point which exists as part of 2D loop of points which describe an outline of a
9/// component or board section.
10///
11/// Used repeatedly in the IDF format to represent points in a loop.
12/// First mention here:
13/// http://www.simplifiedsolutionsinc.com/images/idf_v30_spec.pdf#page=10 in Record 3
14#[derive(Debug, PartialEq, Clone, Default, PartialOrd)]
15pub struct Point {
16 /// The label of the loop the point exist in, 0 for counter-clockwise, 1 for clockwise.
17 pub loop_label: u32,
18 /// The x coordinate of the point.
19 pub x: f32,
20 /// The y coordinate of the point.
21 pub y: f32,
22 /// 0 for a straight line, between 0 and 360 for an arc, 360 for a full circle.
23 pub angle: f32,
24}
25
26/// Parses a point from the input string.
27///
28/// # Example
29/// ```
30/// use idf_parser::point::{point, Point};
31/// let input = "0 100.0 200.0 45.0";
32///
33/// let (remaining, point) = point(input).unwrap();
34/// assert_eq!(point, Point { loop_label: 0, x: 100.0, y: 200.0, angle: 45.0 });
35/// ```
36pub fn point(input: &str) -> IResult<&str, Point> {
37 let (remaining, (loop_label, x, y, angle)) =
38 ws_separated!((u32, float, float, float)).parse(input)?;
39 let point = Point {
40 loop_label,
41 x,
42 y,
43 angle,
44 };
45 Ok((remaining, point))
46}
47
48#[cfg(test)]
49
50mod tests {
51 use super::*;
52
53 #[test]
54 fn test_point() {
55 let input = "0 100.0 200.0 45.0";
56 let (remaining, point) = point(input).unwrap();
57 assert_eq!(remaining, "");
58 assert_eq!(
59 point,
60 Point {
61 loop_label: 0,
62 x: 100.0,
63 y: 200.0,
64 angle: 45.0
65 }
66 );
67 }
68}