Skip to content

Instantly share code, notes, and snippets.

@archer884
Last active August 29, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save archer884/8157a089788fab45b628 to your computer and use it in GitHub Desktop.
Save archer884/8157a089788fab45b628 to your computer and use it in GitHub Desktop.
Distances and conversions
use std::fmt;
use std::ops::Add;
trait Distance {
type Value;
fn to_normal(&self) -> f64;
fn from_normal(f64) -> Self::Value;
}
/// This is an attempt at providing a default implementation of the add trait on the Distance trait
/// rather than having to provide a specific implementation for every implementor of Distance. It
/// doesn't actually work.
//impl<T, D: Distance> Add<D> for Distance<Value=T> {
// type Output = <Self as Distance>::Value;
//
// fn add(self, rhs: D) -> Self::Output {
// Self::Output::from_normal(self.to_normal() + rhs.to_normal())
// }
//}
#[derive(Copy, Clone)]
struct Inches(f64);
impl Distance for Inches {
type Value = Inches;
fn to_normal(&self) -> f64 { self.0 * 2.54 / 100.0 }
fn from_normal(d: f64) -> Self::Value { Inches(d / 2.54 * 100.0) }
}
impl<D: Distance> Add<D> for Inches {
type Output = Inches;
fn add(self, rhs: D) -> Self::Output {
Self::Output::from_normal(self.to_normal() + rhs.to_normal())
}
}
impl Add<f64> for Inches {
type Output = Inches;
fn add(self, rhs: f64) -> Self::Output {
Inches(self.0 + rhs)
}
}
impl fmt::Display for Inches {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Copy, Clone)]
struct Centimeters(f64);
impl Distance for Centimeters {
type Value = Centimeters;
fn to_normal(&self) -> f64 { self.0 / 100.0 }
fn from_normal(d: f64) -> Self::Value { Centimeters(d * 100.0) }
}
impl<D: Distance> Add<D> for Centimeters {
type Output = Centimeters;
fn add(self, rhs: D) -> Self::Output {
Self::Output::from_normal(self.to_normal() + rhs.to_normal())
}
}
impl Add<f64> for Centimeters {
type Output = Centimeters;
fn add(self, rhs: f64) -> Self::Output {
Centimeters(self.0 + rhs)
}
}
impl fmt::Display for Centimeters {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
fn main() {
let foot_long = Inches(12.0);
let inch_long = Centimeters(2.54);
println!("{}", foot_long + inch_long);
println!("{}", foot_long + 1.0);
println!("{}", inch_long + foot_long);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment