1
1
//! A LRM (linear reference model) is an abstract representation
2
- //! where the geometry and real distances are not considered
2
+ //! where the geometry and real distances are not considered.
3
3
4
4
use thiserror:: Error ;
5
5
6
- /// Measurement along the curve . Typically in meters
6
+ /// Measurement along the `Curve` . Typically in meters.
7
7
pub type CurvePosition = f64 ;
8
8
9
- /// Measurement along the scale . Often in meters, but it could be anything
9
+ /// Measurement along the `LrmScale` . Often in meters, but it could be anything.
10
10
pub type ScalePosition = f64 ;
11
11
12
- /// Errors when manipulating a LrmScale
12
+ /// Errors when manipulating a ` LrmScale`.
13
13
#[ derive( Error , Debug , PartialEq ) ]
14
14
pub enum LrmScaleError {
15
- /// Returned when building a scale from a builder and less than 2 named anchors were provided
15
+ /// Returned when building a `LrmScale` from a builder and less than 2 [NamedAnchor] objects were provided.
16
16
#[ error( "a scale needs at least two named anchor" ) ]
17
17
NoEnoughNamedAnchor ,
18
- /// All the named anchors must be unique within a same scale
18
+ /// All the [NamedAnchor] objects must be unique within a same `LrmScale`.
19
19
#[ error( "duplicated anchor: {0}" ) ]
20
20
DuplicatedAnchorName ( String ) ,
21
- /// Could not find the position on the curve as the anchor is not known
21
+ /// Could not find the position on the `Curve` as the [Anchor] is not known.
22
22
#[ error( "anchor is unknown in the LrmScale" ) ]
23
23
UnknownAnchorName ,
24
- /// Could not find an anchor that matches a given offset
24
+ /// Could not find an [Anchor] that matches a given offset.
25
25
#[ error( "no anchor found" ) ]
26
26
NoAnchorFound ,
27
27
}
28
28
29
- /// An anchor is a reference point that is well known from which the location is computed
29
+ /// An `Anchor` is a reference point that is well known from which the location is computed.
30
30
#[ derive( PartialEq , Debug ) ]
31
-
32
31
pub struct Anchor {
33
- /// Some anchors might not be named
34
- /// e.g. the first anchor of the LRM
32
+ /// Some `Anchor` objects might not be named,
33
+ /// e.g. the first anchor of the LRM.
35
34
pub id : Option < String > ,
36
35
37
- /// Distance from the start of the scale in the scale space. Can be negative
36
+ /// Distance from the start of the scale in the scale space, can be negative.
38
37
pub scale_position : ScalePosition ,
39
38
40
- /// Real distance from the start of the curve
41
- /// The curve might not start at the same 0 (e.g. the curve is longer than the scale)
42
- /// or the curve might not progress at the same rate (e.g. the curve is a schematic representation that distorts distances)
39
+ /// Real distance from the start of the `Curve`.
40
+ /// The `Curve` might not start at the same 0 (e.g. the `Curve` is longer than the scale),
41
+ /// or the `Curve` might not progress at the same rate (e.g. the `Curve` is a schematic representation that distorts distances).
43
42
pub curve_position : CurvePosition ,
44
43
}
45
44
46
45
impl Anchor {
47
- /// Build a named anchor
46
+ /// Builds a named `Anchor`.
48
47
pub fn new ( name : & str , scale_position : ScalePosition , curve_position : CurvePosition ) -> Self {
49
48
Self {
50
49
id : Some ( name. to_owned ( ) ) ,
@@ -53,7 +52,7 @@ impl Anchor {
53
52
}
54
53
}
55
54
56
- /// Build an unnamed anchor
55
+ /// Builds an unnamed `Anchor`.
57
56
pub fn new_unnamed ( scale_position : ScalePosition , curve_position : CurvePosition ) -> Self {
58
57
Self {
59
58
id : None ,
@@ -71,43 +70,43 @@ impl Anchor {
71
70
}
72
71
}
73
72
74
- // Private struct to be used when we only deal with anchor that have names
73
+ // Private struct to be used when we only deal with Anchor that has name.
75
74
struct NamedAnchor {
76
75
id : String ,
77
76
scale_position : ScalePosition ,
78
77
curve_position : CurvePosition ,
79
78
}
80
79
81
- /// A helper to build a scale by adding consecutives anchors with relative distances
82
- /// When having all the anchors and their distances in both scale and real position,
83
- /// it is simpler to directly build the LrmScale from an Vec<Anchor>
84
- /// Using the builder will however ensure that the scale is valid
80
+ /// An helper to build a scale by adding consecutive [Anchor] objects with relative distances.
81
+ /// When having all the `Anchor` objects and their distances in both scale and real position,
82
+ /// it is simpler to directly build the [ LrmScale] from an ` Vec<Anchor>`.
83
+ /// Using the builder will however ensure that the scale is valid.
85
84
pub struct ScaleBuilder {
86
85
anchors : Vec < Anchor > ,
87
86
}
88
87
89
88
impl ScaleBuilder {
90
- /// Create a new scale with an initial anchor
89
+ /// Creates a new scale with an initial [Anchor].
91
90
pub fn new ( anchor : Anchor ) -> Self {
92
91
Self {
93
92
anchors : vec ! [ anchor] ,
94
93
}
95
94
}
96
95
97
- /// Builds a named anchor and adds it to the scale builder
98
- /// Distances are relative to previous anchor
96
+ /// Builds a named [Anchor] and adds it to the `ScaleBuilder`.
97
+ /// Distances are relative to previous `Anchor`.
99
98
pub fn add_named ( self , id : & str , scale_dist : ScalePosition , curve_dist : CurvePosition ) -> Self {
100
99
self . add ( Some ( id. to_owned ( ) ) , scale_dist, curve_dist)
101
100
}
102
101
103
- /// Builds an unnamed anchor and adds it to the scale builder
104
- /// Distances are relative to previous anchor
102
+ /// Builds an unnamed [Anchor] and adds it to the `ScaleBuilder`.
103
+ /// Distances are relative to previous `Anchor`.
105
104
pub fn add_unnamed ( self , scale_dist : ScalePosition , curve_dist : CurvePosition ) -> Self {
106
105
self . add ( None , scale_dist, curve_dist)
107
106
}
108
107
109
- /// Builds an anchor and adds it to the scale builder
110
- /// Distances are relative to previous anchor
108
+ /// Builds an [Anchor] and adds it to the `ScaleBuilder`.
109
+ /// Distances are relative to previous `Anchor`.
111
110
pub fn add (
112
111
mut self ,
113
112
id : Option < String > ,
@@ -127,9 +126,9 @@ impl ScaleBuilder {
127
126
self
128
127
}
129
128
130
- /// Requires at least one named anchor
131
- /// Will fail if none is present and if the anchors names are duplicated
132
- /// This will consume the builder that can not be used after
129
+ /// Requires at least one named [Anchor].
130
+ /// Will fail if none is present and if the `Anchor` names are duplicated.
131
+ /// This will consume the `ScaleBuilder` that can not be used after.
133
132
pub fn build ( self , id : & str ) -> Result < LrmScale , LrmScaleError > {
134
133
let mut names = std:: collections:: HashSet :: new ( ) ;
135
134
for anchor in self . anchors . iter ( ) {
@@ -151,20 +150,20 @@ impl ScaleBuilder {
151
150
}
152
151
}
153
152
154
- /// A measure defines a location on the LRM scale
155
- /// It is given as an anchor name and an offset on that scale
156
- /// It is often represented as 12+100 to say “100 scale units after the anchor 12”
153
+ /// A measure defines a location on the [LrmScale].
154
+ /// It is given as an [Anchor] name and an ` offset` on that scale.
155
+ /// It is often represented as ` 12+100` to say ` “100 scale units after the Anchor 12`”.
157
156
pub struct LrmScaleMeasure {
158
- /// Name of the anchor . While it is often named after a kilometer position
159
- /// it can be anything (a letter, a landmark)
157
+ /// ` Name` of the [Anchor] . While it is often named after a kilometer position,
158
+ /// it can be anything (a letter, a landmark).
160
159
pub anchor_name : String ,
161
- /// The offset from the anchor in the scale units
162
- /// there is no guarantee that its value matches actual distance on the curve and is defined in scale units
160
+ /// The ` offset` from the anchor in the scale units.
161
+ /// there is no guarantee that its value matches actual distance on the `Curve` and is defined in scale units.
163
162
pub scale_offset : ScalePosition ,
164
163
}
165
164
166
165
impl LrmScaleMeasure {
167
- /// Build a new LrmMeasure from an anchor name and the offset on the scale
166
+ /// Builds a new ` LrmMeasure` from an [Anchor] ` name` and the ` offset` on the [LrmScale].
168
167
pub fn new ( anchor_name : & str , scale_offset : ScalePosition ) -> Self {
169
168
Self {
170
169
anchor_name : anchor_name. to_owned ( ) ,
@@ -173,18 +172,18 @@ impl LrmScaleMeasure {
173
172
}
174
173
}
175
174
176
- /// Represents an a LRM Scale and allows to map [Measure] to a position along a curve
175
+ /// Represents an `LrmScale` and allows to map [Measure] to a position along a `Curve`.
177
176
#[ derive( PartialEq , Debug ) ]
178
177
pub struct LrmScale {
179
- /// Unique identifier
178
+ /// Unique identifier.
180
179
pub id : String ,
181
- /// The anchors are reference points on the scale from which relative distances are used
180
+ /// The [Anchor] objects are reference points on the scale from which relative distances are used.
182
181
pub anchors : Vec < Anchor > ,
183
182
}
184
183
185
184
impl LrmScale {
186
- /// Locates a point along a curve given an anchor and a offset
187
- /// The offset might be negative
185
+ /// Locates a point along a `Curve` given an [Anchor] and an ` offset`,
186
+ /// which might be negative.
188
187
pub fn locate_point ( & self , measure : & LrmScaleMeasure ) -> Result < CurvePosition , LrmScaleError > {
189
188
let named_anchor = self
190
189
. iter_named ( )
@@ -200,20 +199,20 @@ impl LrmScale {
200
199
Ok ( named_anchor. curve_position + curve_interval * measure. scale_offset / scale_interval)
201
200
}
202
201
203
- /// Returns a measure given a distance along the curve
204
- /// The corresponding anchor is the named anchor that gives the smallest positive offset
205
- /// If such an anchor does not exists, the first named anchor is used
202
+ /// Returns a measure given a distance along the `Curve`.
203
+ /// The corresponding [Anchor] is the named `Anchor` that gives the smallest positive ` offset`.
204
+ /// If such an `Anchor` does not exists, the first named `Anchor` is used.
206
205
pub fn locate_anchor (
207
206
& self ,
208
207
curve_position : CurvePosition ,
209
208
) -> Result < LrmScaleMeasure , LrmScaleError > {
210
- // First we find the nearest named anchor to the curve
209
+ // First, we find the nearest named Anchor to the Curve.
211
210
let named_anchor = self
212
211
. nearest_named ( curve_position)
213
212
. ok_or ( LrmScaleError :: NoAnchorFound ) ?;
214
213
215
- // Then we search the nearest anchor that will be the reference
216
- // to convert from curve units to scale units
214
+ // Then we search the nearest Anchor that will be the reference
215
+ // to convert from Curve units to scale units.
217
216
let nearest_anchor = if named_anchor. curve_position < curve_position {
218
217
self . next_anchor ( & named_anchor. id )
219
218
. or ( self . previous_anchor ( & named_anchor. id ) )
@@ -233,12 +232,12 @@ impl LrmScale {
233
232
}
234
233
235
234
fn nearest_named ( & self , curve_position : CurvePosition ) -> Option < NamedAnchor > {
236
- // Tries to find the anchor whose curve_position is the biggest possible, yet smaller than curve position
235
+ // Tries to find the Anchor whose curve_position is the biggest possible, yet smaller than Curve position
237
236
// Otherwise take the first named
238
237
// Anchor names ----A----B----
239
238
// Curve positions 2 3
240
- // With curve position = 2.1, we want A
241
- // With curve position = 2.9, we want A
239
+ // With Curve position = 2.1, we want A
240
+ // With Curve position = 2.9, we want A
242
241
// 3.5, we want B
243
242
// 1.5, we want A
244
243
self . iter_named ( )
@@ -247,7 +246,7 @@ impl LrmScale {
247
246
. or_else ( || self . iter_named ( ) . next ( ) )
248
247
}
249
248
250
- // Find the closest anchor before the anchor having the name `name`
249
+ // Finds the closest Anchor before the Anchor having the name `name`
251
250
fn previous_anchor ( & self , name : & str ) -> Option < & Anchor > {
252
251
self . anchors
253
252
. iter ( )
@@ -256,15 +255,15 @@ impl LrmScale {
256
255
. nth ( 1 )
257
256
}
258
257
259
- // Find the closest anchor after the anchor having the name `name`
258
+ // Finds the closest Anchor after the Anchor having the name `name`
260
259
fn next_anchor ( & self , name : & str ) -> Option < & Anchor > {
261
260
self . anchors
262
261
. iter ( )
263
262
. skip_while ( |anchor| anchor. id . as_deref ( ) != Some ( name) )
264
263
. nth ( 1 )
265
264
}
266
265
267
- // Iterates only on named anchors
266
+ // Iterates only on named Anchor objects
268
267
fn iter_named ( & self ) -> impl DoubleEndedIterator < Item = NamedAnchor > + ' _ {
269
268
self . anchors . iter ( ) . filter_map ( |anchor| anchor. as_named ( ) )
270
269
}
@@ -287,12 +286,12 @@ mod tests {
287
286
assert_eq ! ( scale. anchors[ 0 ] . curve_position, 0. ) ;
288
287
assert_eq ! ( scale. anchors[ 1 ] . curve_position, 100. ) ;
289
288
290
- // Missing named anchor
289
+ // Missing named Anchor
291
290
let b = ScaleBuilder :: new ( Anchor :: new_unnamed ( 0. , 0. ) ) ;
292
291
let scale = b. build ( "id" ) ;
293
292
assert_eq ! ( scale, Err ( LrmScaleError :: NoEnoughNamedAnchor ) ) ;
294
293
295
- // Duplicated name
294
+ // Duplicated names
296
295
let scale = ScaleBuilder :: new ( Anchor :: new ( "a" , 0. , 0. ) )
297
296
. add_named ( "a" , 100. , 100. )
298
297
. build ( "id" ) ;
@@ -316,7 +315,7 @@ mod tests {
316
315
Ok ( -50. )
317
316
) ;
318
317
319
- // Unknown anchor
318
+ // Unknown Anchor
320
319
assert_eq ! (
321
320
scale. locate_point( & LrmScaleMeasure :: new( "c" , 5. ) ) ,
322
321
Err ( LrmScaleError :: UnknownAnchorName )
@@ -366,22 +365,22 @@ mod tests {
366
365
. build ( "id" )
367
366
. unwrap ( ) ;
368
367
369
- // Unamed ----position----Named
368
+ // Unnamed ----position----Named
370
369
let measure = scale. locate_anchor ( 150. ) . unwrap ( ) ;
371
370
assert_eq ! ( measure. anchor_name, "a" ) ;
372
371
assert_eq ! ( measure. scale_offset, -0.5 ) ;
373
372
374
- // position----Unamed ----Named
373
+ // position----Unnamed ----Named
375
374
let measure = scale. locate_anchor ( 50. ) . unwrap ( ) ;
376
375
assert_eq ! ( measure. anchor_name, "a" ) ;
377
376
assert_eq ! ( measure. scale_offset, -1.5 ) ;
378
377
379
- // Unamed ----Named----position----Unamed
378
+ // Unnamed ----Named----position----Unnamed
380
379
let measure = scale. locate_anchor ( 350. ) . unwrap ( ) ;
381
380
assert_eq ! ( measure. anchor_name, "b" ) ;
382
381
assert_eq ! ( measure. scale_offset, 0.5 ) ;
383
382
384
- // Unamed ----Named----Unamed ----position
383
+ // Unnamed ----Named----Unnamed ----position
385
384
let measure = scale. locate_anchor ( 500. ) . unwrap ( ) ;
386
385
assert_eq ! ( measure. anchor_name, "b" ) ;
387
386
assert_eq ! ( measure. scale_offset, 2. ) ;
0 commit comments