Skip to content

Instantly share code, notes, and snippets.

@henninglive
Created May 24, 2017 15:50
Show Gist options
  • Select an option

  • Save henninglive/53a4886114c254315283b44c9108be80 to your computer and use it in GitHub Desktop.

Select an option

Save henninglive/53a4886114c254315283b44c9108be80 to your computer and use it in GitHub Desktop.
use std::any::{Any, TypeId};
use std::collections::BTreeMap;
trait AnySlice {
fn as_any_mut(&mut self) -> &mut Any;
fn any_get(&self, index: usize) -> Option<&Any>;
fn any_len(&self) -> usize;
}
struct AnyCollection(BTreeMap<TypeId, Box<AnySlice>>);
impl<T: Any> AnySlice for Vec<T> {
fn as_any_mut(&mut self) -> &mut Any {
self as &mut Any
}
fn any_get(&self, index: usize) -> Option<&Any> {
self.get(index).map(|r| r as &Any)
}
fn any_len(&self) -> usize {
self.len()
}
}
impl AnyCollection {
fn new() -> AnyCollection {
AnyCollection(BTreeMap::new())
}
fn push<T: Any>(&mut self, value: T) {
let s = self.0.entry(TypeId::of::<T>())
.or_insert(Box::new(Vec::<T>::new()));
let v = s.as_any_mut().downcast_mut::<Vec<T>>().unwrap();
v.push(value);
}
fn pop<T: Any>(&mut self) -> Option<T> {
self.0.get_mut(&TypeId::of::<T>()).and_then(|s| {
s.as_any_mut().downcast_mut::<Vec<T>>().unwrap().pop()
})
}
fn get(&self, mut index: usize) -> Option<&Any> {
for s in self.0.values() {
let len = s.any_len();
if index < len {
return s.any_get(index);
}
index -= len;
}
return None;
}
}
fn main() {
let mut l = AnyCollection::new();
l.push("test".to_owned());
l.push(2u32);
println!("{}", l.get(0).and_then(|r| r.downcast_ref::<String>()).unwrap());
println!("{}", l.get(1).and_then(|r| r.downcast_ref::<u32>()).unwrap());
println!("{}", l.pop::<String>().unwrap());
println!("{}", l.pop::<u32>().unwrap());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment