1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
/// Sod stands for Static or Dynamic. An enum to encapsulate values which /// are either dynamically, heap-allocated values, or statics. /// /// This allows us to define default primitives which are used throughout /// without the overhead of reference counting, while still supporting the /// flexibility to create primitives dynamically. /// /// Thanks to the `Deref` implementation, either variants are treated like /// the inner type without needing to worry about which it is. /// /// Many thanks to [panicbit](https://github.com/panicbit) for helping to /// get the `Deref` implementation working to make all the magic happen. use std::sync::Arc; use std::ops::Deref; #[derive(PartialEq, PartialOrd)] /// Enum to hold either static references or reference-counted owned objects. /// Implements `Deref` to `T` for ease of use. /// Since internal data is either a static reference, or an `Arc`, cloning /// is a cheap operation. pub enum Sod<T: ?Sized + 'static> { /// Static reference to T Static(&'static T), /// Dynamically allocated T, on the heap, atomically reference-counted. Dynamic(Arc<Box<T>>), } impl<T: ?Sized> Deref for Sod<T> { type Target = T; fn deref(&self) -> &T { match *self { Sod::Static(t) => t, Sod::Dynamic(ref t) => t, } } } impl<T: ?Sized> Clone for Sod<T> { fn clone(&self) -> Self { match *self { Sod::Static(t) => Sod::Static(t), Sod::Dynamic(ref t) => Sod::Dynamic(t.clone()), } } }