diff --git a/README.md b/README.md index 381a110..9b8da5e 100644 --- a/README.md +++ b/README.md @@ -12,4 +12,10 @@ The schema is described in [schema/lrs.fbs](schema/lrs.fbs). The library is writ If your contribution changes the schema, you will need to generate the file with flatc. The version must be the release 23.5.26. Do not use a version built from master. -`flatc -o src --rust schema/lrs.fbs` \ No newline at end of file +`flatc -o src --rust schema/lrs.fbs` + +## Norms + +### Comment convention + +See [How to write documentation in Rust](https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html) to keep the code clean and clear (also [this](https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text) for other examples). \ No newline at end of file diff --git a/src/lrm_scale.rs b/src/lrm_scale.rs index 189460b..15bba70 100644 --- a/src/lrm_scale.rs +++ b/src/lrm_scale.rs @@ -1,50 +1,49 @@ //! A LRM (linear reference model) is an abstract representation -//! where the geometry and real distances are not considered +//! where the geometry and real distances are not considered. use thiserror::Error; -/// Measurement along the curve. Typically in meters +/// Measurement along the `Curve`. Typically in meters. pub type CurvePosition = f64; -/// Measurement along the scale. Often in meters, but it could be anything +/// Measurement along the `LrmScale`. Often in meters, but it could be anything. pub type ScalePosition = f64; -/// Errors when manipulating a LrmScale +/// Errors when manipulating a `LrmScale`. #[derive(Error, Debug, PartialEq)] pub enum LrmScaleError { - /// Returned when building a scale from a builder and less than 2 named anchors were provided + /// Returned when building a `LrmScale` from a builder and less than 2 [NamedAnchor] objects were provided. #[error("a scale needs at least two named anchor")] NoEnoughNamedAnchor, - /// All the named anchors must be unique within a same scale + /// All the [NamedAnchor] objects must be unique within a same `LrmScale`. #[error("duplicated anchor: {0}")] DuplicatedAnchorName(String), - /// Could not find the position on the curve as the anchor is not known + /// Could not find the position on the `Curve` as the [Anchor] is not known. #[error("anchor is unknown in the LrmScale")] UnknownAnchorName, - /// Could not find an anchor that matches a given offset + /// Could not find an [Anchor] that matches a given offset. #[error("no anchor found")] NoAnchorFound, } -/// An anchor is a reference point that is well known from which the location is computed +/// An `Anchor` is a reference point that is well known from which the location is computed. #[derive(PartialEq, Debug)] - pub struct Anchor { - /// Some anchors might not be named - /// e.g. the first anchor of the LRM + /// Some `Anchor` objects might not be named, + /// e.g. the first anchor of the LRM. pub id: Option, - /// Distance from the start of the scale in the scale space. Can be negative + /// Distance from the start of the scale in the scale space, can be negative. pub scale_position: ScalePosition, - /// Real distance from the start of the curve - /// The curve might not start at the same 0 (e.g. the curve is longer than the scale) - /// or the curve might not progress at the same rate (e.g. the curve is a schematic representation that distorts distances) + /// Real distance from the start of the `Curve`. + /// The `Curve` might not start at the same 0 (e.g. the `Curve` is longer than the scale), + /// or the `Curve` might not progress at the same rate (e.g. the `Curve` is a schematic representation that distorts distances) pub curve_position: CurvePosition, } impl Anchor { - /// Build a named anchor + /// Builds a named `Anchor` pub fn new(name: &str, scale_position: ScalePosition, curve_position: CurvePosition) -> Self { Self { id: Some(name.to_owned()), @@ -53,7 +52,7 @@ impl Anchor { } } - /// Build an unnamed anchor + /// Builds an unnamed `Anchor`. pub fn new_unnamed(scale_position: ScalePosition, curve_position: CurvePosition) -> Self { Self { id: None, @@ -71,43 +70,43 @@ impl Anchor { } } -// Private struct to be used when we only deal with anchor that have names +// Private struct to be used when we only deal with Anchor that has name. struct NamedAnchor { id: String, scale_position: ScalePosition, curve_position: CurvePosition, } -/// A helper to build a scale by adding consecutives anchors with relative distances -/// When having all the anchors and their distances in both scale and real position, -/// it is simpler to directly build the LrmScale from an Vec -/// Using the builder will however ensure that the scale is valid +/// An helper to build a scale by adding consecutive [Anchor] objects with relative distances. +/// When having all the `Anchor` objects and their distances in both scale and real position, +/// it is simpler to directly build the [LrmScale] from an `Vec`. +/// Using the builder will however ensure that the scale is valid. pub struct ScaleBuilder { anchors: Vec, } impl ScaleBuilder { - /// Create a new scale with an initial anchor + /// Creates a new scale with an initial [Anchor]. pub fn new(anchor: Anchor) -> Self { Self { anchors: vec![anchor], } } - /// Builds a named anchor and adds it to the scale builder - /// Distances are relative to previous anchor + /// Builds a named [Anchor] and adds it to the `ScaleBuilder`. + /// Distances are relative to previous `Anchor`. pub fn add_named(self, id: &str, scale_dist: ScalePosition, curve_dist: CurvePosition) -> Self { self.add(Some(id.to_owned()), scale_dist, curve_dist) } - /// Builds an unnamed anchor and adds it to the scale builder - /// Distances are relative to previous anchor + /// Builds an unnamed [Anchor] and adds it to the `ScaleBuilder`. + /// Distances are relative to previous `Anchor`. pub fn add_unnamed(self, scale_dist: ScalePosition, curve_dist: CurvePosition) -> Self { self.add(None, scale_dist, curve_dist) } - /// Builds an anchor and adds it to the scale builder - /// Distances are relative to previous anchor + /// Builds an [Anchor] and adds it to the `ScaleBuilder`. + /// Distances are relative to previous `Anchor`. pub fn add( mut self, id: Option, @@ -127,9 +126,9 @@ impl ScaleBuilder { self } - /// Requires at least one named anchor - /// Will fail if none is present and if the anchors names are duplicated - /// This will consume the builder that can not be used after + /// Requires at least one named [Anchor]. + /// Will fail if none is present and if the `Anchor` names are duplicated. + /// This will consume the `ScaleBuilder` that can not be used after. pub fn build(self, id: &str) -> Result { let mut names = std::collections::HashSet::new(); for anchor in self.anchors.iter() { @@ -151,20 +150,20 @@ impl ScaleBuilder { } } -/// A measure defines a location on the LRM scale -/// It is given as an anchor name and an offset on that scale -/// It is often represented as 12+100 to say “100 scale units after the anchor 12” +/// A measure defines a location on the [LrmScale]. +/// It is given as an [Anchor] name and an `offset` on that scale. +/// It is often represented as `12+100` to say `“100 scale units after the Anchor 12`”. pub struct LrmScaleMeasure { - /// Name of the anchor. While it is often named after a kilometer position - /// it can be anything (a letter, a landmark) + /// `Name` of the [Anchor]. While it is often named after a kilometer position, + /// it can be anything (a letter, a landmark). pub anchor_name: String, - /// The offset from the anchor in the scale units - /// there is no guarantee that its value matches actual distance on the curve and is defined in scale units + /// The `offset` from the anchor in the scale units. + /// there is no guarantee that its value matches actual distance on the `Curve` and is defined in scale units. pub scale_offset: ScalePosition, } impl LrmScaleMeasure { - /// Build a new LrmMeasure from an anchor name and the offset on the scale + /// Builds a new `LrmMeasure` from an [Anchor] `name` and the `offset` on the [LrmScale]. pub fn new(anchor_name: &str, scale_offset: ScalePosition) -> Self { Self { anchor_name: anchor_name.to_owned(), @@ -173,18 +172,18 @@ impl LrmScaleMeasure { } } -/// Represents an a LRM Scale and allows to map [Measure] to a position along a curve +/// Represents an `LrmScale` and allows to map [Measure] to a position along a `Curve`. #[derive(PartialEq, Debug)] pub struct LrmScale { /// Unique identifier pub id: String, - /// The anchors are reference points on the scale from which relative distances are used + /// The [Anchor] objects are reference points on the scale from which relative distances are used. pub anchors: Vec, } impl LrmScale { - /// Locates a point along a curve given an anchor and a offset - /// The offset might be negative + /// Locates a point along a `Curve` given an [Anchor] and an `offset`, + /// which might be negative. pub fn locate_point(&self, measure: &LrmScaleMeasure) -> Result { let named_anchor = self .iter_named() @@ -200,20 +199,20 @@ impl LrmScale { Ok(named_anchor.curve_position + curve_interval * measure.scale_offset / scale_interval) } - /// Returns a measure given a distance along the curve - /// The corresponding anchor is the named anchor that gives the smallest positive offset - /// If such an anchor does not exists, the first named anchor is used + /// Returns a measure given a distance along the `Curve`. + /// The corresponding [Anchor] is the named `Anchor` that gives the smallest positive `offset`. + /// If such an `Anchor` does not exists, the first named `Anchor` is used. pub fn locate_anchor( &self, curve_position: CurvePosition, ) -> Result { - // First we find the nearest named anchor to the curve + // First, we find the nearest named Anchor to the Curve. let named_anchor = self .nearest_named(curve_position) .ok_or(LrmScaleError::NoAnchorFound)?; - // Then we search the nearest anchor that will be the reference - // to convert from curve units to scale units + // Then we search the nearest Anchor that will be the reference + // to convert from Curve units to scale units let nearest_anchor = if named_anchor.curve_position < curve_position { self.next_anchor(&named_anchor.id) .or(self.previous_anchor(&named_anchor.id)) @@ -233,12 +232,12 @@ impl LrmScale { } fn nearest_named(&self, curve_position: CurvePosition) -> Option { - // Tries to find the anchor whose curve_position is the biggest possible, yet smaller than curve position + // Tries to find the Anchor whose curve_position is the biggest possible, yet smaller than Curve position // Otherwise take the first named // Anchor names ----A----B---- // Curve positions 2 3 - // With curve position = 2.1, we want A - // With curve position = 2.9, we want A + // With Curve position = 2.1, we want A + // With Curve position = 2.9, we want A // 3.5, we want B // 1.5, we want A self.iter_named() @@ -247,7 +246,7 @@ impl LrmScale { .or_else(|| self.iter_named().next()) } - // Find the closest anchor before the anchor having the name `name` + // Finds the closest Anchor before the Anchor having the name `name` fn previous_anchor(&self, name: &str) -> Option<&Anchor> { self.anchors .iter() @@ -256,7 +255,7 @@ impl LrmScale { .nth(1) } - // Find the closest anchor after the anchor having the name `name` + // Finds the closest Anchor after the Anchor having the name `name` fn next_anchor(&self, name: &str) -> Option<&Anchor> { self.anchors .iter() @@ -264,7 +263,7 @@ impl LrmScale { .nth(1) } - // Iterates only on named anchors + // Iterates only on named Anchor objects fn iter_named(&self) -> impl DoubleEndedIterator + '_ { self.anchors.iter().filter_map(|anchor| anchor.as_named()) } @@ -287,12 +286,12 @@ mod tests { assert_eq!(scale.anchors[0].curve_position, 0.); assert_eq!(scale.anchors[1].curve_position, 100.); - // Missing named anchor + // Missing named Anchor let b = ScaleBuilder::new(Anchor::new_unnamed(0., 0.)); let scale = b.build("id"); assert_eq!(scale, Err(LrmScaleError::NoEnoughNamedAnchor)); - // Duplicated name + // Duplicated names let scale = ScaleBuilder::new(Anchor::new("a", 0., 0.)) .add_named("a", 100., 100.) .build("id"); @@ -316,7 +315,7 @@ mod tests { Ok(-50.) ); - // Unknown anchor + // Unknown Anchor assert_eq!( scale.locate_point(&LrmScaleMeasure::new("c", 5.)), Err(LrmScaleError::UnknownAnchorName) @@ -366,22 +365,22 @@ mod tests { .build("id") .unwrap(); - // Unamed----position----Named + // Unnamed----position----Named let measure = scale.locate_anchor(150.).unwrap(); assert_eq!(measure.anchor_name, "a"); assert_eq!(measure.scale_offset, -0.5); - // position----Unamed----Named + // position----Unnamed----Named let measure = scale.locate_anchor(50.).unwrap(); assert_eq!(measure.anchor_name, "a"); assert_eq!(measure.scale_offset, -1.5); - // Unamed----Named----position----Unamed + // Unnamed----Named----position----Unnamed let measure = scale.locate_anchor(350.).unwrap(); assert_eq!(measure.anchor_name, "b"); assert_eq!(measure.scale_offset, 0.5); - // Unamed----Named----Unamed----position + // Unnamed----Named----Unnamed----position let measure = scale.locate_anchor(500.).unwrap(); assert_eq!(measure.anchor_name, "b"); assert_eq!(measure.scale_offset, 2.);