title: Swift protocol extensions with enums
body: <p>So I have several enums representing various unit systems:</p>
  
  <pre><code>enum MassUnit:Double{
       case Pound = 453.59237, Ounce = 28.349523125, Gram = 1.0, Kilogram = 1000.0;
  }
  enum VolumeUnit:Double{
      case Teaspoon = 1, Tablespoon = 3, Cup = 48, Pint = 96, Quart = 192, Gallon = 768, Liter = 202.884136211, Milliliter = 0.202884136211
  }
  enum TimeUnit:Double{
      case Second = 1, Minute = 60, Hour = 3600, Day = 86400, Week = 604800, Year = 31536000
  }
  </code></pre>
  
  <p>What I would like to do is be able to convert from one unit to another, eg from year to seconds.  To do this I've ensured that the raw values for my enums correspond to the converting multipliers, eg 1 Min = 60 seconds.  Thus, given x amount of some unit, the conversion is simply</p>
  
  <pre><code>x * rawValue1 / rawValue2 // rawValue2 = rawValue of desired unit.
  </code></pre>
  
  <p>While that conversion is simple enough, I would love to be efficient and use a protocol:</p>
  
  <pre><code>protocol Convertable{
      func convert(inputAmount inputAmount:Double, outputUnit:Self)-&gt;Double;
  }
  </code></pre>
  
  <p>Then, I could extend the enum:</p>
  
  <pre><code>extension TimeUnit:Convertable{
      func convert(inputAmount inputAmount: Double, outputUnit: TimeUnit) -&gt; Double {
          return inputAmount * self.rawValue / outputUnit.rawValue;
      }
  }
  </code></pre>
  
  <p>Then I could simply convert like this:</p>
  
  <pre><code>TimeUnit.Year.convert(inputAmount: 2.54, outputUnit: .Second)
  // returns 80101440
  </code></pre>
  
  <p>This is great, however, depending on how many units I want to convert, there would be a lot of duplication of the same code.</p>
  
  <p>So, what I would like to do is somehow use a protocol extension.</p>
  
  <pre><code>extension Convertable{
      func convert(inputAmount inputAmount: Double, outputUnit: Self) -&gt; Double {
          return inputAmount * self.rawValue / outputUnit.rawValue;// Compile error...
      }
  }
  </code></pre>
  
  <p>This is where I get into trouble, the output unit is declared as self, which knows nothing about rawValue. </p>
  
  <p>Any ideas?</p>