use std::fmt;
use std::fmt::Write;
#[derive(Clone)]
pub struct PolyPointBuilder {
precision: usize,
points: String,
}
impl fmt::Display for PolyPointBuilder {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.points)?;
Ok(())
}
}
impl From<PolyPointBuilder> for String {
fn from(poly: PolyPointBuilder) -> Self {
poly.points
}
}
impl PolyPointBuilder {
pub(crate) fn new() -> Self {
PolyPointBuilder {
precision: 2,
points: String::new(),
}
}
pub fn precision(&mut self, digits: usize) -> &mut Self {
self.precision = digits;
self
}
fn value(&mut self, v: f64) {
write!(&mut self.points, "{v:.0$}", self.precision).unwrap();
if self.precision > 0 {
while self.points.ends_with('0') {
self.points.pop();
}
if self.points.ends_with('.') {
self.points.pop();
}
}
}
fn point(&mut self, x: f64, y: f64) {
if !self.points.is_empty() {
self.points.push(' ');
}
self.value(x);
self.points.push(',');
self.value(y);
}
pub fn add<P, V>(&mut self, p: P) -> &mut Self
where
P: Into<(V, V)>,
V: Into<f64> + Copy,
{
let p = p.into();
let (x, y) = (p.0.into(), p.1.into());
self.point(x, y);
self
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn empty() {
let poly = PolyPointBuilder::new();
assert_eq!(poly.to_string(), "");
}
#[test]
fn mv() {
let mut poly = PolyPointBuilder::new();
poly.add([1, 2]);
assert_eq!(poly.to_string(), "1,2");
}
#[test]
fn line() {
let mut poly = PolyPointBuilder::new();
poly.add([1, 2]);
poly.add([2, 1]);
assert_eq!(poly.to_string(), "1,2 2,1");
}
#[test]
fn rounding() {
let mut poly = PolyPointBuilder::new();
poly.add([2.0001, 0.003]);
assert_eq!(poly.to_string(), "2,0");
}
#[test]
fn two_decimal_places() {
let mut poly = PolyPointBuilder::new();
poly.add([2.2222, 9.994]);
poly.add([4.444444, 8.88888]);
assert_eq!(poly.to_string(), "2.22,9.99 4.44,8.89");
}
#[test]
fn three_decimal_places() {
let mut poly = PolyPointBuilder::new();
poly.precision(3);
poly.add([2.2222, 9.994]);
poly.add([4.444444, 8.88888]);
poly.add([5.444444, 8.88888]);
assert_eq!(poly.to_string(), "2.222,9.994 4.444,8.889 5.444,8.889");
}
}