From b56e60b752ed3c8b17e5f9dc9bc5330cc05477e1 Mon Sep 17 00:00:00 2001 From: chrysn Date: Tue, 28 Apr 2020 16:30:21 +0200 Subject: [PATCH] Make Entry type public This allows external code to express constraints like `N: ArrayLength>`, which is not possible with the enum hidden in a module. Entry is made into a struct that contains a single enum; this appears to be the common pattern while enums can not yet be opaque types. --- src/lib.rs | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 09c7d10..23ab064 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,16 +77,13 @@ impl Key { } } -/// Module to hide the Entry type which needs to be public due to the generic-array internals. -mod entry { - pub enum Entry { - Used(IT), - EmptyNext(usize), - EmptyLast - } -} +pub struct Entry(EntryInner); -use entry::Entry; +enum EntryInner { + Used(IT), + EmptyNext(usize), + EmptyLast +} // Data type that stores values and returns a key that can be used to manipulate // the stored values. @@ -106,7 +103,7 @@ impl Slots let size = N::to_usize(); Self { - items: GenericArray::generate(|i| i.checked_sub(1).map(Entry::EmptyNext).unwrap_or(Entry::EmptyLast)), + items: GenericArray::generate(|i| Entry(i.checked_sub(1).map(EntryInner::EmptyNext).unwrap_or(EntryInner::EmptyLast))), next_free: size.checked_sub(1), free_count: size } @@ -122,8 +119,8 @@ impl Slots fn free(&mut self, idx: usize) { self.items[idx] = match self.next_free { - Some(n) => Entry::EmptyNext(n), - None => Entry::EmptyLast + Some(n) => Entry(EntryInner::EmptyNext(n)), + None => Entry(EntryInner::EmptyLast), }; self.next_free = Some(idx); self.free_count += 1; @@ -131,9 +128,9 @@ impl Slots fn alloc(&mut self) -> Option { let index = self.next_free?; - self.next_free = match self.items[index] { - Entry::EmptyNext(n) => Some(n), - Entry::EmptyLast => None, + self.next_free = match self.items[index].0 { + EntryInner::EmptyNext(n) => Some(n), + EntryInner::EmptyLast => None, _ => unreachable!("Non-empty item in entry behind free chain"), }; self.free_count -= 1; @@ -143,7 +140,7 @@ impl Slots pub fn store(&mut self, item: IT) -> Result, IT> { match self.alloc() { Some(i) => { - self.items[i] = Entry::Used(item); + self.items[i] = Entry(EntryInner::Used(item)); Ok(Key::new(i)) } None => Err(item) @@ -151,10 +148,10 @@ impl Slots } pub fn take(&mut self, key: Key) -> IT { - let taken = core::mem::replace(&mut self.items[key.index], Entry::EmptyLast); + let taken = core::mem::replace(&mut self.items[key.index], Entry(EntryInner::EmptyLast)); self.free(key.index); - match taken { - Entry::Used(item) => item, + match taken.0 { + EntryInner::Used(item) => item, _ => panic!() } } @@ -167,15 +164,15 @@ impl Slots } pub fn try_read(&self, key: usize, function: F) -> Option where F: FnOnce(&IT) -> T { - match &self.items[key] { - Entry::Used(item) => Some(function(&item)), + match &self.items[key].0 { + EntryInner::Used(item) => Some(function(&item)), _ => None } } pub fn modify(&mut self, key: &Key, function: F) -> T where F: FnOnce(&mut IT) -> T { - match self.items[key.index] { - Entry::Used(ref mut item) => function(item), + match self.items[key.index].0 { + EntryInner::Used(ref mut item) => function(item), _ => panic!() } }