Advertisement
Guest User

Untitled

a guest
Nov 25th, 2015
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.72 KB | None | 0 0
  1. //! Evolv-ty: Enforcing evolving protocols with Rust's type system.
  2. //!
  3. //! Pros:
  4. //! - Avoid regressions in the protocol
  5. //! - Tiny and simple implementation
  6. //! - Deprecated functions can be trivially no-op
  7. //! - Types may be changed trivially
  8. //!
  9. //! Cons:
  10. //! - Tracking versions can get verbose and messy
  11.  
  12. /// Marker trait: 'Self' fits within the range requirement of `L..` (inclusive)
  13. pub trait Start<L> {}
  14. /// Marker trait: 'Self' fits within the range requirement of `..R` (exclusive)
  15. pub trait End<R> {}
  16.  
  17. /// Allow structs to use the evolving properties
  18. trait Pick<V> { type Ty; }
  19.  
  20. impl<L, R> Start<L> for R where L: End<R> {}
  21.  
  22. macro_rules! ordered {
  23. () => {};
  24. ($head:ident $($tail:ident)*) => {
  25. #[allow(non_camel_case_types)]
  26. pub enum $head {}
  27. impl Start<$head> for $head {}
  28. $(impl End<$tail> for $head {})*
  29. ordered!{ $($tail)* }
  30. }
  31. }
  32.  
  33. #[cfg(test)]
  34. mod test {
  35. use {Start, End, Pick};
  36.  
  37. ordered!{
  38. Alice // Alpha
  39. Bob // Beta
  40. Carol // Beta RC1
  41. Dave // Beta RC2
  42. Stable_1_0_0 // Cannonical version numbers
  43. Nightly_2_0_0 // Not yet officially in the protocol
  44. }
  45.  
  46. // Version tagging may be relative to assist with stability tests
  47. type Alpha = Alice;
  48. type Beta = Dave;
  49. type Stable = Stable_1_0_0;
  50. type Nightly = Nightly_2_0_0;
  51.  
  52. enum FooAB {}
  53.  
  54. // impl<R: Start<Alpha> + End<Beta>> Pick<R> for FooAB {
  55. impl Pick<Alpha> for FooAB {
  56. type Ty = u8;
  57. }
  58.  
  59. impl<R: Start<Beta>> Pick<R> for FooAB {
  60. type Ty = u16;
  61. }
  62.  
  63. pub struct Foo<V> where FooAB: Pick<V> {
  64. a: <FooAB as Pick<V>>::Ty,
  65. marker: ::std::marker::PhantomData<V>
  66. }
  67.  
  68. #[cfg(not(feature = "no_backwards"))]
  69. impl<V: Start<Alice> + End<Bob>> Foo<V> {
  70. // Deprecated since Bob
  71. fn alice() {
  72. println!("Deprecated function: fn alice. Alice <= Version < Bob")
  73. }
  74. }
  75.  
  76. impl<V: Start<Bob>> Foo<V> {
  77. // Updated implementation of alice.
  78. fn alice() {
  79. println!("Alice: Version = Bob+")
  80. }
  81.  
  82. // Added in Beta
  83. fn bob() where V: Start<Bob> {}
  84. // Added in Beta RC 1
  85. fn carol() where V: Start<Carol> {}
  86.  
  87. // Unofficially deprecated since 2.0
  88. fn beta_nightly() where V: Start<Beta> + End<Nightly> {}
  89. }
  90.  
  91. #[test]
  92. fn typecheck() {
  93. // Fails to typecheck when --features no_backwards
  94. Foo::<Alice>::alice(); // Alice == Alice < Bob
  95.  
  96. Foo::<Bob>::alice(); // Bob > Alice
  97. Foo::<Carol>::bob(); // Carol > Bob
  98. Foo::<Carol>::carol(); // Carol == Carol
  99.  
  100. Foo::<Stable>::beta_nightly();
  101. if cfg!(feature = "debug_tests") {
  102. panic!("Debug")
  103. }
  104. }
  105. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement