Skip to content

Instantly share code, notes, and snippets.

@qryxip
Created February 17, 2017 07:58
Show Gist options
  • Save qryxip/e12acf591d99f6e8e435f6da1ef1a109 to your computer and use it in GitHub Desktop.
Save qryxip/e12acf591d99f6e8e435f6da1ef1a109 to your computer and use it in GitHub Desktop.
#!cargo script
use std::fmt;
use std::fmt::{Display, Formatter};
use std::marker::PhantomData;
use std::ops::Add;
use std::cmp::{Eq, PartialEq};
struct Length<V, M> where M: Measure {
value: V,
measure: PhantomData<M>,
}
impl<V, M> Clone for Length<V, M> where V: Copy, M: Measure {
fn clone(&self) -> Length<V, M> {
Length { value: self.value, measure: PhantomData }
}
}
impl<V, M> Copy for Length<V, M> where V: Copy, M: Measure {}
impl<V, M> PartialEq for Length<V, M> where V: Eq, M: Measure {
fn eq(&self, other: &Length<V, M>) -> bool {
self.value == other.value
}
}
impl<V, M> Eq for Length<V, M> where V: Eq, M: Measure {}
impl<V, M> Display for Length<V, M> where V: Display, M: Measure {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.value)
}
}
impl<V, M> Add<Length<V, M>> for Length<V, M> where V: Add<Output = V>, M: Measure {
type Output = Length<V, M>;
fn add(self, other: Length<V, M>) -> Length<V, M> {
Length { value: self.value + other.value, measure: PhantomData }
}
}
trait Measure<M = Self> where M: Measure {
fn new<V>(value: V) -> Length<V, M> {
Length { value: value, measure: PhantomData }
}
}
struct Inch;
struct Meter;
impl Measure for Inch {}
impl Measure for Meter {}
fn main() {
let hundred_inches = Inch::new(100);
let ten_inches = Inch::new(10);
println!("100 inches + 10 inches = {}", hundred_inches + ten_inches);
let hundred_meters = Meter::new(100);
let ten_meters = Meter::new(10);
println!("100 meters == 10 meters = {}", hundred_meters == ten_meters);
// Compilation Error ↓
//Inch::new(100) + Inch::new(100.0);
//Inch::new(100) == Meter::new(100);
//Inch::new(1.0) == Inch::new(1.0); // Why
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment