diff --git a/src/impls/codec.rs b/src/impls/codec.rs index 5e52afb..943cada 100644 --- a/src/impls/codec.rs +++ b/src/impls/codec.rs @@ -1,6 +1,6 @@ //! A region that encodes its contents. -use crate::{OwnedRegion, Push, Region}; +use crate::{OwnedRegion, Push, ReadRegion, Region}; pub use self::misra_gries::MisraGries; pub use dictionary::DictionaryCodec; @@ -81,17 +81,26 @@ impl Clone for CodecRegion { } } -impl Region for CodecRegion +impl ReadRegion for CodecRegion where - for<'a> R: Region = &'a [u8]> + 'a, + for<'a> R: ReadRegion = &'a [u8]> + 'a, { type Owned = Vec; type ReadItem<'a> = &'a [u8] - where - Self: 'a; + where + Self: 'a; type Index = R::Index; + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + self.codec.decode(self.inner.index(index)) + } +} + +impl Region for CodecRegion +where + for<'a> R: Region = &'a [u8]> + 'a, +{ /// Construct a region that can absorb the contents of `regions` in the future. fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where @@ -104,10 +113,6 @@ where } } - fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - self.codec.decode(self.inner.index(index)) - } - fn reserve_regions<'a, I>(&mut self, regions: I) where Self: 'a, @@ -138,7 +143,7 @@ impl Push<&[u8]> for CodecRegion where for<'a> R: Region = &'a [u8]> + Push<&'a [u8]> + 'a, { - fn push(&mut self, item: &[u8]) -> as Region>::Index { + fn push(&mut self, item: &[u8]) -> as ReadRegion>::Index { self.codec.encode(item, &mut self.inner) } } diff --git a/src/impls/columns.rs b/src/impls/columns.rs index e7b97a4..6944822 100644 --- a/src/impls/columns.rs +++ b/src/impls/columns.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use crate::impls::deduplicate::ConsecutiveOffsetPairs; use crate::impls::offsets::OffsetOptimized; use crate::{CopyIter, IntoOwned}; -use crate::{OwnedRegion, Push, Region}; +use crate::{OwnedRegion, Push, ReadRegion, Region}; /// A region that can store a variable number of elements per row. /// @@ -24,7 +24,7 @@ use crate::{OwnedRegion, Push, Region}; /// Copy a table-like structure: /// ``` /// # use flatcontainer::impls::deduplicate::ConsecutiveOffsetPairs; -/// # use flatcontainer::{ColumnsRegion, Push, Region, StringRegion}; +/// # use flatcontainer::{ColumnsRegion, Push, ReadRegion, Region, StringRegion}; /// let data = [ /// vec![], /// vec!["1"], @@ -58,7 +58,7 @@ use crate::{OwnedRegion, Push, Region}; )] pub struct ColumnsRegion where - R: Region, + R: ReadRegion, { /// Indices to address rows in `inner`. For each row, we remember /// an index for each column. @@ -84,14 +84,26 @@ where } } -impl Region for ColumnsRegion +impl ReadRegion for ColumnsRegion where - R: Region, + R: ReadRegion, { type Owned = Vec; type ReadItem<'a> = ReadColumns<'a, R> where Self: 'a; type Index = usize; + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + ReadColumns(Ok(ReadColumnsInner { + columns: &self.inner, + index: self.indices.index(index), + })) + } +} + +impl Region for ColumnsRegion +where + R: Region, +{ fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where Self: 'a, @@ -111,13 +123,6 @@ where } } - fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - ReadColumns(Ok(ReadColumnsInner { - columns: &self.inner, - index: self.indices.index(index), - })) - } - fn reserve_regions<'a, I>(&mut self, regions: I) where Self: 'a, @@ -175,11 +180,11 @@ where /// Read the values of a row. pub struct ReadColumns<'a, R>(Result, &'a [R::Owned]>) where - R: Region; + R: ReadRegion; struct ReadColumnsInner<'a, R> where - R: Region, + R: ReadRegion, { /// Storage for columns. columns: &'a [R], @@ -189,7 +194,7 @@ where impl<'a, R> Clone for ReadColumns<'a, R> where - R: Region, + R: ReadRegion, { fn clone(&self) -> Self { *self @@ -198,19 +203,19 @@ where impl<'a, R> Clone for ReadColumnsInner<'a, R> where - R: Region, + R: ReadRegion, { fn clone(&self) -> Self { *self } } -impl<'a, R> Copy for ReadColumns<'a, R> where R: Region {} -impl<'a, R> Copy for ReadColumnsInner<'a, R> where R: Region {} +impl<'a, R> Copy for ReadColumns<'a, R> where R: ReadRegion {} +impl<'a, R> Copy for ReadColumnsInner<'a, R> where R: ReadRegion {} impl<'a, R> Debug for ReadColumns<'a, R> where - R: Region, + R: ReadRegion, R::ReadItem<'a>: Debug, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -220,7 +225,7 @@ where impl<'a, R> ReadColumns<'a, R> where - R: Region, + R: ReadRegion, { /// Iterate the individual values of a row. #[must_use] @@ -255,9 +260,10 @@ where } } } + impl<'a, R> ReadColumnsInner<'a, R> where - R: Region, + R: ReadRegion, { /// Get the element at `offset`. #[must_use] @@ -280,7 +286,7 @@ where impl<'a, R> IntoOwned<'a> for ReadColumns<'a, R> where - R: Region, + R: ReadRegion, { type Owned = Vec; @@ -305,7 +311,7 @@ where impl<'a, R> IntoIterator for &ReadColumns<'a, R> where - R: Region, + R: ReadRegion, { type Item = R::ReadItem<'a>; type IntoIter = ReadColumnsIter<'a, R>; @@ -321,18 +327,18 @@ where } /// An iterator over the elements of a row. -pub struct ReadColumnsIter<'a, R: Region>( +pub struct ReadColumnsIter<'a, R: ReadRegion>( Result, std::slice::Iter<'a, R::Owned>>, ); /// An iterator over the elements of a row. -pub struct ReadColumnsIterInner<'a, R: Region> { +pub struct ReadColumnsIterInner<'a, R: ReadRegion> { iter: std::iter::Zip, std::slice::Iter<'a, R>>, } impl<'a, R> Iterator for ReadColumnsIter<'a, R> where - R: Region, + R: ReadRegion, { type Item = R::ReadItem<'a>; @@ -346,7 +352,7 @@ where impl<'a, R> Iterator for ReadColumnsIterInner<'a, R> where - R: Region, + R: ReadRegion, { type Item = R::ReadItem<'a>; @@ -357,9 +363,9 @@ where impl Push> for ColumnsRegion where - for<'a> R: Region + Push<::ReadItem<'a>>, + for<'a> R: ReadRegion + Push<::ReadItem<'a>>, { - fn push(&mut self, item: ReadColumns<'_, R>) -> as Region>::Index { + fn push(&mut self, item: ReadColumns<'_, R>) -> as ReadRegion>::Index { // Ensure all required regions exist. while self.inner.len() < item.len() { self.inner.push(R::default()); @@ -375,9 +381,9 @@ where impl<'a, R, T> Push<&'a [T]> for ColumnsRegion where - R: Region + Push<&'a T>, + R: ReadRegion + Push<&'a T>, { - fn push(&mut self, item: &'a [T]) -> as Region>::Index { + fn push(&mut self, item: &'a [T]) -> as ReadRegion>::Index { // Ensure all required regions exist. while self.inner.len() < item.len() { self.inner.push(R::default()); @@ -393,9 +399,9 @@ where impl Push<[T; N]> for ColumnsRegion where - R: Region + Push, + R: ReadRegion + Push, { - fn push(&mut self, item: [T; N]) -> as Region>::Index { + fn push(&mut self, item: [T; N]) -> as ReadRegion>::Index { // Ensure all required regions exist. while self.inner.len() < item.len() { self.inner.push(R::default()); @@ -411,9 +417,9 @@ where impl<'a, R, T, const N: usize> Push<&'a [T; N]> for ColumnsRegion where - R: Region + Push<&'a T>, + R: ReadRegion + Push<&'a T>, { - fn push(&mut self, item: &'a [T; N]) -> as Region>::Index { + fn push(&mut self, item: &'a [T; N]) -> as ReadRegion>::Index { // Ensure all required regions exist. while self.inner.len() < item.len() { self.inner.push(R::default()); @@ -429,9 +435,9 @@ where impl Push> for ColumnsRegion where - R: Region + Push, + R: ReadRegion + Push, { - fn push(&mut self, item: Vec) -> as Region>::Index { + fn push(&mut self, item: Vec) -> as ReadRegion>::Index { // Ensure all required regions exist. while self.inner.len() < item.len() { self.inner.push(R::default()); @@ -447,9 +453,9 @@ where impl<'a, R, T> Push<&'a Vec> for ColumnsRegion where - R: Region + Push<&'a T>, + R: ReadRegion + Push<&'a T>, { - fn push(&mut self, item: &'a Vec) -> as Region>::Index { + fn push(&mut self, item: &'a Vec) -> as ReadRegion>::Index { // Ensure all required regions exist. while self.inner.len() < item.len() { self.inner.push(R::default()); @@ -465,11 +471,11 @@ where impl Push> for ColumnsRegion where - R: Region + Push, + R: ReadRegion + Push, I: IntoIterator, { #[inline] - fn push(&mut self, item: CopyIter) -> as Region>::Index { + fn push(&mut self, item: CopyIter) -> as ReadRegion>::Index { let iter = item.0.into_iter().enumerate().map(|(index, value)| { // Ensure all required regions exist. if self.inner.len() <= index { diff --git a/src/impls/deduplicate.rs b/src/impls/deduplicate.rs index e53073c..e604075 100644 --- a/src/impls/deduplicate.rs +++ b/src/impls/deduplicate.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::impls::offsets::{OffsetContainer, OffsetOptimized}; -use crate::{Push, Region, ReserveItems}; +use crate::{Push, ReadRegion, Region, ReserveItems}; /// A region to deduplicate consecutive equal items. /// @@ -20,7 +20,7 @@ use crate::{Push, Region, ReserveItems}; /// ``` #[derive(Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct CollapseSequence { +pub struct CollapseSequence { /// Inner region. inner: R, /// The index of the last pushed item. @@ -50,11 +50,17 @@ impl Default for CollapseSequence { } } -impl Region for CollapseSequence { +impl ReadRegion for CollapseSequence { type Owned = R::Owned; type ReadItem<'a> = R::ReadItem<'a> where Self: 'a; type Index = R::Index; + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + self.inner.index(index) + } +} + +impl Region for CollapseSequence { fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where Self: 'a, @@ -65,10 +71,6 @@ impl Region for CollapseSequence { } } - fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - self.inner.index(index) - } - fn reserve_regions<'a, I>(&mut self, regions: I) where Self: 'a, @@ -99,7 +101,7 @@ where R: Region + Push, for<'a> T: PartialEq>, { - fn push(&mut self, item: T) -> as Region>::Index { + fn push(&mut self, item: T) -> as ReadRegion>::Index { if let Some(last_index) = self.last_index { if item == self.inner.index(last_index) { return last_index; @@ -122,7 +124,7 @@ where /// The following example shows that two inserts into a copy region have a collapsible index: /// ``` /// use flatcontainer::impls::deduplicate::{CollapseSequence, ConsecutiveOffsetPairs}; -/// use flatcontainer::{Push, OwnedRegion, Region, StringRegion}; +/// use flatcontainer::{Push, OwnedRegion, ReadRegion, Region, StringRegion}; /// let mut r = >>::default(); /// /// let index: usize = r.push(&b"abc"); @@ -172,18 +174,30 @@ where } } -impl Region for ConsecutiveOffsetPairs +impl ReadRegion for ConsecutiveOffsetPairs where - R: Region, + R: ReadRegion, O: OffsetContainer, { type Owned = R::Owned; type ReadItem<'a> = R::ReadItem<'a> - where - Self: 'a; + where + Self: 'a; type Index = usize; + #[inline] + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + self.inner + .index((self.offsets.index(index), self.offsets.index(index + 1))) + } +} + +impl Region for ConsecutiveOffsetPairs +where + R: Region, + O: OffsetContainer, +{ #[inline] fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where @@ -198,12 +212,6 @@ where } } - #[inline] - fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - self.inner - .index((self.offsets.index(index), self.offsets.index(index + 1))) - } - #[inline] fn reserve_regions<'a, I>(&mut self, regions: I) where @@ -242,7 +250,7 @@ where O: OffsetContainer, { #[inline] - fn push(&mut self, item: T) -> as Region>::Index { + fn push(&mut self, item: T) -> as ReadRegion>::Index { let index = self.inner.push(item); debug_assert_eq!(index.0, self.last_index); self.last_index = index.1; diff --git a/src/impls/huffman_container.rs b/src/impls/huffman_container.rs index 75c2086..49c234b 100644 --- a/src/impls/huffman_container.rs +++ b/src/impls/huffman_container.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; -use crate::{Push, Region}; +use crate::{Push, ReadRegion, Region}; use self::encoded::Encoded; use self::huffman::Huffman; @@ -47,15 +47,28 @@ impl Clone for HuffmanContainer { } } -impl Region for HuffmanContainer +impl ReadRegion for HuffmanContainer where B: Ord + Clone + Sized + 'static, { type Owned = Vec; type ReadItem<'a> = Wrapped<'a, B>; - type Index = (usize, usize); + fn index(&self, (lower, upper): Self::Index) -> Self::ReadItem<'_> { + match &self.inner { + Ok((huffman, bytes, _bits)) => { + Wrapped::encoded(Encoded::new(huffman, bytes, (lower, upper))) + } + Err(raw) => Wrapped::decoded(&raw[lower..upper]), + } + } +} + +impl Region for HuffmanContainer +where + B: Ord + Clone + Sized + 'static, +{ fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where Self: 'a, @@ -79,15 +92,6 @@ where } } - fn index(&self, (lower, upper): Self::Index) -> Self::ReadItem<'_> { - match &self.inner { - Ok((huffman, bytes, _bits)) => { - Wrapped::encoded(Encoded::new(huffman, bytes, (lower, upper))) - } - Err(raw) => Wrapped::decoded(&raw[lower..upper]), - } - } - fn reserve_regions<'a, I>(&mut self, _regions: I) where Self: 'a, diff --git a/src/impls/mirror.rs b/src/impls/mirror.rs index 2574d49..72943ca 100644 --- a/src/impls/mirror.rs +++ b/src/impls/mirror.rs @@ -6,7 +6,7 @@ use std::marker::PhantomData; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use crate::{Containerized, Index, IntoOwned, Push, Region, ReserveItems}; +use crate::{Containerized, Index, IntoOwned, Push, ReadRegion, Region, ReserveItems}; /// A region for types where the read item type is equal to the index type. /// @@ -19,7 +19,7 @@ use crate::{Containerized, Index, IntoOwned, Push, Region, ReserveItems}; /// /// For [`MirrorRegion`]s, we can index with a copy type: /// ``` -/// # use flatcontainer::{MirrorRegion, Region}; +/// # use flatcontainer::{MirrorRegion, ReadRegion, Region}; /// let r = >::default(); /// let output: u8 = r.index(42); /// assert_eq!(output, 42); @@ -40,7 +40,7 @@ impl Debug for MirrorRegion { } } -impl Region for MirrorRegion +impl ReadRegion for MirrorRegion where for<'a> T: Index + IntoOwned<'a, Owned = T>, { @@ -48,6 +48,16 @@ where type ReadItem<'a> = T where T: 'a; type Index = T; + #[inline] + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + index + } +} + +impl Region for MirrorRegion +where + for<'a> T: Index + IntoOwned<'a, Owned = T>, +{ #[inline] fn merge_regions<'a>(_regions: impl Iterator + Clone) -> Self where @@ -55,12 +65,6 @@ where { Self::default() } - - #[inline] - fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - index - } - #[inline(always)] fn reserve_regions<'a, I>(&mut self, _regions: I) where diff --git a/src/impls/offsets.rs b/src/impls/offsets.rs index 617721d..8de511e 100644 --- a/src/impls/offsets.rs +++ b/src/impls/offsets.rs @@ -308,7 +308,7 @@ impl OffsetContainer for Vec { #[cfg(test)] mod tests { use crate::impls::deduplicate::ConsecutiveOffsetPairs; - use crate::{Push, Region, SliceRegion, StringRegion}; + use crate::{Push, ReadRegion, Region, SliceRegion, StringRegion}; use super::*; diff --git a/src/impls/option.rs b/src/impls/option.rs index b56b6c2..d0cf546 100644 --- a/src/impls/option.rs +++ b/src/impls/option.rs @@ -3,7 +3,7 @@ #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use crate::{Containerized, IntoOwned, Push, Region, ReserveItems}; +use crate::{Containerized, IntoOwned, Push, ReadRegion, Region, ReserveItems}; impl Containerized for Option { type Region = OptionRegion; @@ -15,7 +15,7 @@ impl Containerized for Option { /// /// The region can hold options: /// ``` -/// # use flatcontainer::{Containerized, Push, OptionRegion, Region}; +/// # use flatcontainer::{Containerized, Push, OptionRegion, ReadRegion, Region}; /// let mut r = ::Region>>::default(); /// /// let some_index = r.push(Some(123)); @@ -43,11 +43,18 @@ impl Clone for OptionRegion { } } -impl Region for OptionRegion { +impl ReadRegion for OptionRegion { type Owned = Option; - type ReadItem<'a> = Option<::ReadItem<'a>> where Self: 'a; + type ReadItem<'a> = Option<::ReadItem<'a>> where Self: 'a; type Index = Option; + #[inline] + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + index.map(|t| self.inner.index(t)) + } +} + +impl Region for OptionRegion { #[inline] fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where @@ -58,11 +65,6 @@ impl Region for OptionRegion { } } - #[inline] - fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - index.map(|t| self.inner.index(t)) - } - #[inline] fn reserve_regions<'a, I>(&mut self, regions: I) where @@ -122,7 +124,7 @@ where TR: Region + Push, { #[inline] - fn push(&mut self, item: Option) -> as Region>::Index { + fn push(&mut self, item: Option) -> as ReadRegion>::Index { item.map(|t| self.inner.push(t)) } } @@ -132,7 +134,7 @@ where TR: Region + Push<&'a T>, { #[inline] - fn push(&mut self, item: &'a Option) -> as Region>::Index { + fn push(&mut self, item: &'a Option) -> as ReadRegion>::Index { item.as_ref().map(|t| self.inner.push(t)) } } diff --git a/src/impls/result.rs b/src/impls/result.rs index 5a26670..700c3e6 100644 --- a/src/impls/result.rs +++ b/src/impls/result.rs @@ -3,7 +3,7 @@ #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use crate::{Containerized, IntoOwned, Push, Region, ReserveItems}; +use crate::{Containerized, IntoOwned, Push, ReadRegion, Region, ReserveItems}; impl Containerized for Result { type Region = ResultRegion; @@ -15,7 +15,7 @@ impl Containerized for Result { /// /// Add results to a result region: /// ``` -/// use flatcontainer::{Containerized, Push, Region, ResultRegion}; +/// use flatcontainer::{Containerized, Push, ReadRegion, Region, ResultRegion}; /// let mut r = /// ::Region, ::Region>>::default(); /// @@ -46,15 +46,29 @@ impl Clone for ResultRegion { } } -impl Region for ResultRegion +impl ReadRegion for ResultRegion where - T: Region, - E: Region, + T: ReadRegion, + E: ReadRegion, { type Owned = Result; type ReadItem<'a> = Result, E::ReadItem<'a>> where Self: 'a; type Index = Result; + #[inline] + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + match index { + Ok(index) => Ok(self.oks.index(index)), + Err(index) => Err(self.errs.index(index)), + } + } +} + +impl Region for ResultRegion +where + T: Region, + E: Region, +{ #[inline] fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where @@ -66,14 +80,6 @@ where } } - #[inline] - fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - match index { - Ok(index) => Ok(self.oks.index(index)), - Err(index) => Err(self.errs.index(index)), - } - } - #[inline] fn reserve_regions<'a, I>(&mut self, regions: I) where @@ -139,7 +145,7 @@ where EC: Region + Push, { #[inline] - fn push(&mut self, item: Result) -> as Region>::Index { + fn push(&mut self, item: Result) -> as ReadRegion>::Index { match item { Ok(t) => Ok(self.oks.push(t)), Err(e) => Err(self.errs.push(e)), @@ -153,7 +159,7 @@ where EC: Region + Push<&'a E>, { #[inline] - fn push(&mut self, item: &'a Result) -> as Region>::Index { + fn push(&mut self, item: &'a Result) -> as ReadRegion>::Index { match item { Ok(t) => Ok(self.oks.push(t)), Err(e) => Err(self.errs.push(e)), diff --git a/src/impls/slice.rs b/src/impls/slice.rs index cdfbb20..1645fd9 100644 --- a/src/impls/slice.rs +++ b/src/impls/slice.rs @@ -8,7 +8,7 @@ use std::ops::{Deref, Range}; use serde::{Deserialize, Serialize}; use crate::impls::offsets::OffsetContainer; -use crate::{Containerized, IntoOwned, Push, Region, ReserveItems}; +use crate::{Containerized, IntoOwned, Push, ReadRegion, Region, ReserveItems}; impl Containerized for Vec { type Region = SliceRegion; @@ -33,7 +33,7 @@ impl Containerized for [T; N] { /// /// We fill some data into a slice region and use the [`ReadSlice`] to extract it later. /// ``` -/// use flatcontainer::{Containerized, Push, Region, SliceRegion}; +/// use flatcontainer::{Containerized, Push, ReadRegion, Region, SliceRegion}; /// let mut r = ::Region>>::default(); /// /// let panagram_en = "The quick fox jumps over the lazy dog" @@ -53,7 +53,7 @@ impl Containerized for [T; N] { /// ``` #[derive(Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct SliceRegion::Index>> { +pub struct SliceRegion::Index>> { /// Container of slices. slices: O, /// Inner region. @@ -78,11 +78,22 @@ where } } -impl> Region for SliceRegion { +impl> ReadRegion for SliceRegion { type Owned = Vec; type ReadItem<'a> = ReadSlice<'a, R, O> where Self: 'a; type Index = (usize, usize); + #[inline] + fn index(&self, (start, end): Self::Index) -> Self::ReadItem<'_> { + ReadSlice(Ok(ReadSliceInner { + region: self, + start, + end, + })) + } +} + +impl> Region for SliceRegion { #[inline] fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where @@ -94,15 +105,6 @@ impl> Region for SliceRegion { } } - #[inline] - fn index(&self, (start, end): Self::Index) -> Self::ReadItem<'_> { - ReadSlice(Ok(ReadSliceInner { - region: self, - start, - end, - })) - } - #[inline] fn reserve_regions<'a, I>(&mut self, regions: I) where @@ -146,11 +148,11 @@ impl> Default for SliceRegion { } /// A helper to read data out of a slice region. -pub struct ReadSlice<'a, R: Region, O: OffsetContainer = Vec<::Index>>( +pub struct ReadSlice<'a, R: ReadRegion, O: OffsetContainer>( Result, &'a [R::Owned]>, ); -impl> ReadSlice<'_, R, O> { +impl> ReadSlice<'_, R, O> { /// Read the n-th item from the underlying region. /// /// # Panics @@ -223,13 +225,13 @@ where } } -struct ReadSliceInner<'a, R: Region, O: OffsetContainer = Vec<::Index>> { +struct ReadSliceInner<'a, R: ReadRegion, O: OffsetContainer> { region: &'a SliceRegion, start: usize, end: usize, } -impl> ReadSliceInner<'_, R, O> { +impl> ReadSliceInner<'_, R, O> { /// Read the n-th item from the underlying region. /// /// # Panics @@ -264,7 +266,7 @@ impl> ReadSliceInner<'_, R, O> { } } -impl> Debug for ReadSlice<'_, R, O> +impl> Debug for ReadSlice<'_, R, O> where for<'a> R::ReadItem<'a>: Debug, { @@ -273,26 +275,26 @@ where } } -impl> Clone for ReadSlice<'_, R, O> { +impl> Clone for ReadSlice<'_, R, O> { #[inline] fn clone(&self) -> Self { *self } } -impl> Clone for ReadSliceInner<'_, R, O> { +impl> Clone for ReadSliceInner<'_, R, O> { #[inline] fn clone(&self) -> Self { *self } } -impl> Copy for ReadSlice<'_, R, O> {} -impl> Copy for ReadSliceInner<'_, R, O> {} +impl> Copy for ReadSlice<'_, R, O> {} +impl> Copy for ReadSliceInner<'_, R, O> {} impl<'a, R, O> IntoOwned<'a> for ReadSlice<'a, R, O> where - R: Region, + R: ReadRegion, O: OffsetContainer, { type Owned = Vec; @@ -318,7 +320,7 @@ where } } -impl<'a, R: Region, O: OffsetContainer> IntoIterator for ReadSlice<'a, R, O> { +impl<'a, R: ReadRegion, O: OffsetContainer> IntoIterator for ReadSlice<'a, R, O> { type Item = R::ReadItem<'a>; type IntoIter = ReadSliceIter<'a, R, O>; @@ -335,11 +337,11 @@ impl<'a, R: Region, O: OffsetContainer> IntoIterator for ReadSlice<'a, /// An iterator over the items read from a slice region. #[derive(Debug)] -pub struct ReadSliceIter<'a, C: Region, O: OffsetContainer>( - Result, std::slice::Iter<'a, C::Owned>>, +pub struct ReadSliceIter<'a, R: ReadRegion, O: OffsetContainer>( + Result, std::slice::Iter<'a, R::Owned>>, ); -impl<'a, C: Region, O: OffsetContainer> Clone for ReadSliceIter<'a, C, O> { +impl<'a, R: ReadRegion, O: OffsetContainer> Clone for ReadSliceIter<'a, R, O> { #[inline] fn clone(&self) -> Self { Self(self.0.clone()) @@ -348,20 +350,20 @@ impl<'a, C: Region, O: OffsetContainer> Clone for ReadSliceIter<'a, C, /// An iterator over the items read from a slice region. #[derive(Debug)] -pub struct ReadSliceIterInner<'a, C: Region, O: OffsetContainer>( - &'a SliceRegion, +pub struct ReadSliceIterInner<'a, R: ReadRegion, O: OffsetContainer>( + &'a SliceRegion, Range, ); -impl<'a, C: Region, O: OffsetContainer> Clone for ReadSliceIterInner<'a, C, O> { +impl<'a, R: ReadRegion, O: OffsetContainer> Clone for ReadSliceIterInner<'a, R, O> { #[inline] fn clone(&self) -> Self { Self(self.0, self.1.clone()) } } -impl<'a, C: Region, O: OffsetContainer> Iterator for ReadSliceIter<'a, C, O> { - type Item = C::ReadItem<'a>; +impl<'a, R: ReadRegion, O: OffsetContainer> Iterator for ReadSliceIter<'a, R, O> { + type Item = R::ReadItem<'a>; #[inline] fn next(&mut self) -> Option { @@ -372,8 +374,8 @@ impl<'a, C: Region, O: OffsetContainer> Iterator for ReadSliceIter<'a, } } -impl<'a, C: Region, O: OffsetContainer> Iterator for ReadSliceIterInner<'a, C, O> { - type Item = C::ReadItem<'a>; +impl<'a, R: ReadRegion, O: OffsetContainer> Iterator for ReadSliceIterInner<'a, R, O> { + type Item = R::ReadItem<'a>; #[inline] fn next(&mut self) -> Option { @@ -383,13 +385,13 @@ impl<'a, C: Region, O: OffsetContainer> Iterator for ReadSliceIterInne } } -impl<'a, C, T, O> Push<&'a [T]> for SliceRegion +impl<'a, R, T, O> Push<&'a [T]> for SliceRegion where - C: Region + Push<&'a T>, - O: OffsetContainer, + R: Region + Push<&'a T>, + O: OffsetContainer, { #[inline] - fn push(&mut self, item: &'a [T]) -> as Region>::Index { + fn push(&mut self, item: &'a [T]) -> as ReadRegion>::Index { let start = self.slices.len(); self.slices.extend(item.iter().map(|t| self.inner.push(t))); (start, self.slices.len()) @@ -411,13 +413,13 @@ where } } -impl Push> for SliceRegion +impl Push> for SliceRegion where - C: Region + Push, - O: OffsetContainer, + R: Region + Push, + O: OffsetContainer, { #[inline] - fn push(&mut self, item: Vec) -> as Region>::Index { + fn push(&mut self, item: Vec) -> as ReadRegion>::Index { let start = self.slices.len(); self.slices .extend(item.into_iter().map(|t| self.inner.push(t))); @@ -425,24 +427,24 @@ where } } -impl Push<&Vec> for SliceRegion +impl Push<&Vec> for SliceRegion where - for<'a> C: Region + Push<&'a T>, - O: OffsetContainer, + for<'a> R: Region + Push<&'a T>, + O: OffsetContainer, { #[inline] - fn push(&mut self, item: &Vec) -> as Region>::Index { + fn push(&mut self, item: &Vec) -> as ReadRegion>::Index { self.push(item.as_slice()) } } -impl<'a, C, T, O> Push<&&'a Vec> for SliceRegion +impl<'a, R, T, O> Push<&&'a Vec> for SliceRegion where - C: Region + Push<&'a T>, - O: OffsetContainer, + R: Region + Push<&'a T>, + O: OffsetContainer, { #[inline] - fn push(&mut self, item: &&'a Vec) -> as Region>::Index { + fn push(&mut self, item: &&'a Vec) -> as ReadRegion>::Index { self.push(item.as_slice()) } } @@ -461,13 +463,13 @@ where } } -impl<'a, C, O> Push> for SliceRegion +impl<'a, R, O> Push> for SliceRegion where - C: Region + Push<::ReadItem<'a>>, - O: OffsetContainer, + R: Region + Push<::ReadItem<'a>>, + O: OffsetContainer, { #[inline] - fn push(&mut self, item: ReadSlice<'a, C, O>) -> as Region>::Index { + fn push(&mut self, item: ReadSlice<'a, R, O>) -> as ReadRegion>::Index { match item.0 { Ok(inner) => self.push(inner), Err(slice) => { @@ -482,13 +484,13 @@ where } } -impl<'a, C, O> Push> for SliceRegion +impl<'a, R, O> Push> for SliceRegion where - C: Region + Push<::ReadItem<'a>>, - O: OffsetContainer, + R: Region + Push<::ReadItem<'a>>, + O: OffsetContainer, { #[inline] - fn push(&mut self, item: ReadSliceInner<'a, C, O>) -> as Region>::Index { + fn push(&mut self, item: ReadSliceInner<'a, R, O>) -> as ReadRegion>::Index { let ReadSliceInner { region, start, end } = item; let start_len = self.slices.len(); for index in start..end { @@ -506,7 +508,7 @@ where O: OffsetContainer, { #[inline] - fn push(&mut self, item: [T; N]) -> as Region>::Index { + fn push(&mut self, item: [T; N]) -> as ReadRegion>::Index { self.push(item.as_slice()) } } @@ -517,7 +519,7 @@ where O: OffsetContainer, { #[inline] - fn push(&mut self, item: &'a [T; N]) -> as Region>::Index { + fn push(&mut self, item: &'a [T; N]) -> as ReadRegion>::Index { self.push(item.as_slice()) } } @@ -528,7 +530,7 @@ where O: OffsetContainer, { #[inline] - fn push(&mut self, item: &&'a [T; N]) -> as Region>::Index { + fn push(&mut self, item: &&'a [T; N]) -> as ReadRegion>::Index { self.push(item.as_slice()) } } @@ -548,7 +550,7 @@ where impl<'a, R, O> ReserveItems> for SliceRegion where - R: Region + ReserveItems<::ReadItem<'a>> + 'a, + R: Region + ReserveItems<::ReadItem<'a>> + 'a, O: OffsetContainer, { fn reserve_items(&mut self, items: I) diff --git a/src/impls/slice_copy.rs b/src/impls/slice_copy.rs index 33aa134..fca7f5b 100644 --- a/src/impls/slice_copy.rs +++ b/src/impls/slice_copy.rs @@ -3,7 +3,7 @@ #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use crate::{CopyIter, Push, Region, ReserveItems}; +use crate::{CopyIter, Push, ReadRegion, Region, ReserveItems}; /// A container for owned types. /// @@ -15,7 +15,7 @@ use crate::{CopyIter, Push, Region, ReserveItems}; /// # Examples /// /// ``` -/// use flatcontainer::{Push, OwnedRegion, Region}; +/// use flatcontainer::{Push, OwnedRegion,ReadRegion, Region}; /// let mut r = >::default(); /// /// let panagram_en = "The quick fox jumps over the lazy dog"; @@ -45,7 +45,7 @@ impl Clone for OwnedRegion { } } -impl Region for OwnedRegion +impl ReadRegion for OwnedRegion where [T]: ToOwned, { @@ -53,6 +53,16 @@ where type ReadItem<'a> = &'a [T] where Self: 'a; type Index = (usize, usize); + #[inline] + fn index(&self, (start, end): Self::Index) -> Self::ReadItem<'_> { + &self.slices[start..end] + } +} + +impl Region for OwnedRegion +where + [T]: ToOwned, +{ #[inline] fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where @@ -63,11 +73,6 @@ where } } - #[inline] - fn index(&self, (start, end): Self::Index) -> Self::ReadItem<'_> { - &self.slices[start..end] - } - #[inline] fn reserve_regions<'a, I>(&mut self, regions: I) where @@ -114,7 +119,7 @@ where [T]: ToOwned, { #[inline] - fn push(&mut self, item: [T; N]) -> as Region>::Index { + fn push(&mut self, item: [T; N]) -> as ReadRegion>::Index { let start = self.slices.len(); self.slices.extend(item); (start, self.slices.len()) @@ -123,7 +128,7 @@ where impl Push<&[T; N]> for OwnedRegion { #[inline] - fn push(&mut self, item: &[T; N]) -> as Region>::Index { + fn push(&mut self, item: &[T; N]) -> as ReadRegion>::Index { let start = self.slices.len(); self.slices.extend_from_slice(item); (start, self.slices.len()) @@ -132,7 +137,7 @@ impl Push<&[T; N]> for OwnedRegion { impl Push<&&[T; N]> for OwnedRegion { #[inline] - fn push(&mut self, item: &&[T; N]) -> as Region>::Index { + fn push(&mut self, item: &&[T; N]) -> as ReadRegion>::Index { self.push(*item) } } @@ -149,7 +154,7 @@ impl<'b, T: Clone, const N: usize> ReserveItems<&'b [T; N]> for OwnedRegion { impl Push<&[T]> for OwnedRegion { #[inline] - fn push(&mut self, item: &[T]) -> as Region>::Index { + fn push(&mut self, item: &[T]) -> as ReadRegion>::Index { let start = self.slices.len(); self.slices.extend_from_slice(item); (start, self.slices.len()) @@ -161,7 +166,7 @@ where for<'a> Self: Push<&'a [T]>, { #[inline] - fn push(&mut self, item: &&[T]) -> as Region>::Index { + fn push(&mut self, item: &&[T]) -> as ReadRegion>::Index { self.push(*item) } } @@ -184,7 +189,7 @@ where [T]: ToOwned, { #[inline] - fn push(&mut self, mut item: Vec) -> as Region>::Index { + fn push(&mut self, mut item: Vec) -> as ReadRegion>::Index { let start = self.slices.len(); self.slices.append(&mut item); (start, self.slices.len()) @@ -193,7 +198,7 @@ where impl Push<&Vec> for OwnedRegion { #[inline] - fn push(&mut self, item: &Vec) -> as Region>::Index { + fn push(&mut self, item: &Vec) -> as ReadRegion>::Index { self.push(item.as_slice()) } } @@ -213,7 +218,7 @@ where impl> Push> for OwnedRegion { #[inline] - fn push(&mut self, item: CopyIter) -> as Region>::Index { + fn push(&mut self, item: CopyIter) -> as ReadRegion>::Index { let start = self.slices.len(); self.slices.extend(item.0); (start, self.slices.len()) @@ -236,7 +241,7 @@ where #[cfg(test)] mod tests { - use crate::{CopyIter, Push, Region, ReserveItems}; + use crate::{CopyIter, Push, ReadRegion, ReserveItems}; use super::*; diff --git a/src/impls/string.rs b/src/impls/string.rs index c1d10b0..ace1cb9 100644 --- a/src/impls/string.rs +++ b/src/impls/string.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::impls::slice_copy::OwnedRegion; -use crate::{Containerized, Push, Region, ReserveItems}; +use crate::{Containerized, Push, ReadRegion, Region, ReserveItems}; /// A region to store strings and read `&str`. /// @@ -18,7 +18,7 @@ use crate::{Containerized, Push, Region, ReserveItems}; /// /// We fill some data into a string region and use extract it later. /// ``` -/// use flatcontainer::{Containerized, Push, OwnedRegion, Region, StringRegion}; +/// use flatcontainer::{Containerized, Push, OwnedRegion, ReadRegion, Region, StringRegion}; /// let mut r = ::default(); /// /// let panagram_en = "The quick fox jumps over the lazy dog"; @@ -48,14 +48,25 @@ impl Clone for StringRegion { } } -impl Region for StringRegion +impl ReadRegion for StringRegion where - for<'a> R: Region = &'a [u8]> + 'a, + for<'a> R: ReadRegion = &'a [u8]> + 'a, { type Owned = String; type ReadItem<'a> = &'a str where Self: 'a ; type Index = R::Index; + #[inline] + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + // SAFETY: All Push implementations only accept correct utf8 data + unsafe { std::str::from_utf8_unchecked(self.inner.index(index)) } + } +} + +impl Region for StringRegion +where + for<'a> R: Region = &'a [u8]> + 'a, +{ #[inline] fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where @@ -66,12 +77,6 @@ where } } - #[inline] - fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - // SAFETY: All Push implementations only accept correct utf8 data - unsafe { std::str::from_utf8_unchecked(self.inner.index(index)) } - } - #[inline] fn reserve_regions<'a, I>(&mut self, regions: I) where @@ -113,7 +118,7 @@ where for<'a> R: Region = &'a [u8]> + Push<&'a [u8]> + 'a, { #[inline] - fn push(&mut self, item: String) -> as Region>::Index { + fn push(&mut self, item: String) -> as ReadRegion>::Index { self.push(item.as_str()) } } @@ -123,7 +128,7 @@ where for<'a> R: Region = &'a [u8]> + Push<&'a [u8]> + 'a, { #[inline] - fn push(&mut self, item: &String) -> as Region>::Index { + fn push(&mut self, item: &String) -> as ReadRegion>::Index { self.push(item.as_str()) } } @@ -146,7 +151,7 @@ where for<'a> R: Region = &'a [u8]> + Push<&'a [u8]> + 'a, { #[inline] - fn push(&mut self, item: &str) -> as Region>::Index { + fn push(&mut self, item: &str) -> as ReadRegion>::Index { self.inner.push(item.as_bytes()) } } @@ -156,7 +161,7 @@ where for<'a> R: Region = &'a [u8]> + Push<&'a [u8]> + 'a, { #[inline] - fn push(&mut self, item: &&str) -> as Region>::Index { + fn push(&mut self, item: &&str) -> as ReadRegion>::Index { self.push(*item) } } @@ -189,7 +194,7 @@ where #[cfg(test)] mod tests { - use crate::{IntoOwned, Push, Region, ReserveItems, StringRegion}; + use crate::{IntoOwned, Push, ReadRegion, Region, ReserveItems, StringRegion}; #[test] fn test_inner() { diff --git a/src/impls/tuple.rs b/src/impls/tuple.rs index 17502df..89a1fd6 100644 --- a/src/impls/tuple.rs +++ b/src/impls/tuple.rs @@ -4,7 +4,7 @@ use paste::paste; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use crate::{Containerized, IntoOwned, Push, Region, ReserveItems}; +use crate::{Containerized, IntoOwned, Push, ReadRegion, Region, ReserveItems}; /// The macro creates the region implementation for tuples macro_rules! tuple_flatcontainer { @@ -25,7 +25,7 @@ macro_rules! tuple_flatcontainer { #[allow(non_snake_case)] impl<$($name: Region + Clone),*> Clone for []<$($name),*> where - $(<$name as Region>::Index: crate::Index),* + $(<$name as ReadRegion>::Index: crate::Index),* { fn clone(&self) -> Self { Self { @@ -39,15 +39,28 @@ macro_rules! tuple_flatcontainer { } #[allow(non_snake_case)] - impl<$($name: Region),*> Region for []<$($name),*> + impl<$($name: ReadRegion),*> ReadRegion for []<$($name),*> where - $(<$name as Region>::Index: crate::Index),* + $(<$name as ReadRegion>::Index: crate::Index),* { type Owned = ($($name::Owned,)*); type ReadItem<'a> = ($($name::ReadItem<'a>,)*) where Self: 'a; - type Index = ($($name::Index,)*); + #[inline] + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + let ($($name,)*) = index; + ( + $(self.[].index($name),)* + ) + } + } + + #[allow(non_snake_case)] + impl<$($name: Region),*> Region for []<$($name),*> + where + $(<$name as ReadRegion>::Index: crate::Index),* + { #[inline] fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where @@ -58,13 +71,6 @@ macro_rules! tuple_flatcontainer { } } - #[inline] fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - let ($($name,)*) = index; - ( - $(self.[].index($name),)* - ) - } - #[inline(always)] fn reserve_regions<'a, It>(&mut self, regions: It) where @@ -101,7 +107,7 @@ macro_rules! tuple_flatcontainer { { #[inline] fn push(&mut self, item: ($($name,)*)) - -> <[]<$([<$name _C>]),*> as Region>::Index { + -> <[]<$([<$name _C>]),*> as ReadRegion>::Index { let ($($name,)*) = item; ($(self.[].push($name),)*) } @@ -115,7 +121,7 @@ macro_rules! tuple_flatcontainer { { #[inline] fn push(&mut self, item: &'a ($($name,)*)) - -> <[]<$([<$name _C>]),*> as Region>::Index { + -> <[]<$([<$name _C>]),*> as ReadRegion>::Index { let ($($name,)*) = item; ($(self.[].push($name),)*) } @@ -240,7 +246,7 @@ cfg_if::cfg_if! { #[cfg(test)] mod tests { use crate::impls::tuple::TupleABCRegion; - use crate::{FlatStack, MirrorRegion, Push, Region, StringRegion}; + use crate::{FlatStack, MirrorRegion, Push, ReadRegion, Region, StringRegion}; #[test] fn test_tuple() { diff --git a/src/impls/vec.rs b/src/impls/vec.rs index 712a79d..84b3588 100644 --- a/src/impls/vec.rs +++ b/src/impls/vec.rs @@ -1,12 +1,20 @@ //! Definitions to use `Vec` as a region. -use crate::{Push, Region, ReserveItems}; +use crate::{Push, ReadRegion, Region, ReserveItems}; -impl Region for Vec { +impl ReadRegion for Vec { type Owned = T; - type ReadItem<'a> = &'a T where Self: 'a; + type ReadItem<'a> = &'a T + where + Self: 'a; type Index = usize; + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + &self[index] + } +} + +impl Region for Vec { fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where Self: 'a, @@ -14,10 +22,6 @@ impl Region for Vec { Self::with_capacity(regions.map(Vec::len).sum()) } - fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - &self[index] - } - fn reserve_regions<'a, I>(&mut self, regions: I) where Self: 'a, @@ -77,7 +81,7 @@ impl ReserveItems for Vec { mod tests { #[test] fn vec() { - use crate::{Push, Region, ReserveItems}; + use crate::{Push, ReadRegion, ReserveItems}; let mut region = Vec::::new(); let index = <_ as Push<_>>::push(&mut region, 42); diff --git a/src/lib.rs b/src/lib.rs index 0347288..5455b19 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,14 +33,15 @@ pub trait Index: Copy {} #[cfg(not(feature = "serde"))] impl Index for T {} -/// A region to absorb presented data and present it as a type with a lifetime. +/// A region that we can read from, but not write to. /// -/// This type absorbs data and provides an index to look up an equivalent representation -/// of this data at a later time. It is up to an implementation to select the appropriate -/// presentation of the data, and what data it can absorb. +/// It presents data in an implementation-specific way, encoded by the +/// [`ReadRegion::ReadItem`] associated type, and supports indexing +/// using [`ReadRegion::index`]. The index type is again specific to an +/// implementation. /// -/// Implement the [`Push`] trait for all types that can be copied into a region. -pub trait Region: Default { +/// For a region that is writable, see [`Region`] instead. +pub trait ReadRegion { /// An owned type that can be constructed from a read item. type Owned; @@ -53,15 +54,24 @@ pub trait Region: Default { /// as an opaque type, even if known. type Index: Index; - /// Construct a region that can absorb the contents of `regions` in the future. - fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self - where - Self: 'a; - /// Index into the container. The index must be obtained by /// pushing data into the container. #[must_use] fn index(&self, index: Self::Index) -> Self::ReadItem<'_>; +} + +/// A region to absorb presented data and present it as a type with a lifetime. +/// +/// This type absorbs data and provides an index to look up an equivalent representation +/// of this data at a later time. It is up to an implementation to select the appropriate +/// presentation of the data, and what data it can absorb. +/// +/// Implement the [`Push`] trait for all types that can be copied into a region. +pub trait Region: ReadRegion + Default { + /// Construct a region that can absorb the contents of `regions` in the future. + fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self + where + Self: 'a; /// Ensure that the region can absorb the items of `regions` without reallocation fn reserve_regions<'a, I>(&mut self, regions: I) @@ -439,7 +449,7 @@ mod tests { fn all_types() { fn test_copy(t: T) where - for<'a> R: Push + Push<::ReadItem<'a>>, + for<'a> R: Push + Push<::ReadItem<'a>>, // Make sure that types are debug, even if we don't use this in the test. for<'a> R::ReadItem<'a>: Debug, { @@ -598,7 +608,7 @@ mod tests { fn test_owned() { fn owned_roundtrip(region: &mut R, index: R::Index) where - for<'a> R: Region + Push<<::ReadItem<'a> as IntoOwned<'a>>::Owned>, + for<'a> R: Region + Push<<::ReadItem<'a> as IntoOwned<'a>>::Owned>, for<'a> R::ReadItem<'a>: IntoOwned<'a, Owned = O> + Eq + Debug, { let item = region.index(index); diff --git a/tests/cow.rs b/tests/cow.rs index d82e5b7..ad3b85b 100644 --- a/tests/cow.rs +++ b/tests/cow.rs @@ -4,7 +4,7 @@ use std::fmt::{Debug, Formatter}; use std::marker::PhantomData; -use flatcontainer::{FlatStack, IntoOwned, Push, Region, StringRegion}; +use flatcontainer::{FlatStack, IntoOwned, Push, ReadRegion, Region, StringRegion}; pub struct GatCow<'a, B> where @@ -102,15 +102,25 @@ where #[derive(Default, Debug, Clone)] struct CowRegion(R); -impl Region for CowRegion +impl ReadRegion for CowRegion where - R: Region, + R: ReadRegion, for<'a> R::ReadItem<'a>: Copy, { - type Owned = ::Owned; + type Owned = ::Owned; type ReadItem<'a> = GatCow<'a, R::ReadItem<'a>> where Self: 'a; type Index = R::Index; + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + GatCowInner::Borrowed(self.0.index(index)).into() + } +} + +impl Region for CowRegion +where + R: Region, + for<'a> R::ReadItem<'a>: Copy, +{ fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where Self: 'a, @@ -118,10 +128,6 @@ where Self(R::merge_regions(regions.map(|r| &r.0))) } - fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - GatCowInner::Borrowed(self.0.index(index)).into() - } - fn reserve_regions<'a, I>(&mut self, regions: I) where Self: 'a, diff --git a/tests/person.rs b/tests/person.rs index 514217e..61c498e 100644 --- a/tests/person.rs +++ b/tests/person.rs @@ -1,6 +1,6 @@ //! Test a slightly more struct with nested regions, representing people. -use flatcontainer::{Containerized, FlatStack, IntoOwned, Push, Region, ReserveItems}; +use flatcontainer::{Containerized, FlatStack, IntoOwned, Push, ReadRegion, Region, ReserveItems}; struct Person { name: String, @@ -21,9 +21,9 @@ struct PersonRegion { #[derive(Debug, Clone, Copy)] struct PersonRef<'a> { - name: <::Region as Region>::ReadItem<'a>, - age: <::Region as Region>::ReadItem<'a>, - hobbies: < as Containerized>::Region as Region>::ReadItem<'a>, + name: <::Region as ReadRegion>::ReadItem<'a>, + age: <::Region as ReadRegion>::ReadItem<'a>, + hobbies: < as Containerized>::Region as ReadRegion>::ReadItem<'a>, } impl<'a> IntoOwned<'a> for PersonRef<'a> { @@ -52,15 +52,27 @@ impl<'a> IntoOwned<'a> for PersonRef<'a> { } } -impl Region for PersonRegion { +impl ReadRegion for PersonRegion { type Owned = Person; - type ReadItem<'a> = PersonRef<'a> where Self: 'a; + type ReadItem<'a> = PersonRef<'a> + where + Self: 'a; type Index = ( - <::Region as Region>::Index, - <::Region as Region>::Index, - < as Containerized>::Region as Region>::Index, + <::Region as ReadRegion>::Index, + <::Region as ReadRegion>::Index, + < as Containerized>::Region as ReadRegion>::Index, ); + fn index(&self, (name, age, hobbies): Self::Index) -> Self::ReadItem<'_> { + PersonRef { + name: self.name_container.index(name), + age: self.age_container.index(age), + hobbies: self.hobbies.index(hobbies), + } + } +} + +impl Region for PersonRegion { fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where Self: 'a, @@ -78,14 +90,6 @@ impl Region for PersonRegion { } } - fn index(&self, (name, age, hobbies): Self::Index) -> Self::ReadItem<'_> { - PersonRef { - name: self.name_container.index(name), - age: self.age_container.index(age), - hobbies: self.hobbies.index(hobbies), - } - } - fn reserve_regions<'a, I>(&mut self, regions: I) where Self: 'a, @@ -124,7 +128,7 @@ impl Region for PersonRegion { } impl Push<&Person> for PersonRegion { - fn push(&mut self, item: &Person) -> ::Index { + fn push(&mut self, item: &Person) -> ::Index { let name = self.name_container.push(&item.name); let age = self.age_container.push(item.age); let hobbies = self.hobbies.push(&item.hobbies); @@ -146,7 +150,7 @@ impl<'a> ReserveItems<&'a Person> for PersonRegion { } impl Push> for PersonRegion { - fn push(&mut self, item: PersonRef<'_>) -> ::Index { + fn push(&mut self, item: PersonRef<'_>) -> ::Index { let name = self.name_container.push(item.name); let age = self.age_container.push(item.age); let hobbies = self.hobbies.push(item.hobbies); diff --git a/tests/recursive.rs b/tests/recursive.rs index 2dba7a5..10cccf4 100644 --- a/tests/recursive.rs +++ b/tests/recursive.rs @@ -1,16 +1,16 @@ //! Demonstration of how to encode recursive data structures. use flatcontainer::impls::deduplicate::ConsecutiveOffsetPairs; -use flatcontainer::{IntoOwned, Push, Region, StringRegion}; +use flatcontainer::{IntoOwned, Push, ReadRegion, Region, StringRegion}; #[derive(Clone)] struct List(T, Option>>); -struct ListRef<'a, C: Region>( - Result<(&'a ListRegion, ::Index, Option), &'a List>, +struct ListRef<'a, C: ReadRegion>( + Result<(&'a ListRegion, ::Index, Option), &'a List>, ); -impl<'a, C: Region> ListRef<'a, C> +impl<'a, C: ReadRegion> ListRef<'a, C> where C::Owned: Clone, { @@ -32,7 +32,7 @@ where } } -impl<'a, C: Region> IntoOwned<'a> for ListRef<'a, C> +impl<'a, C: ReadRegion> IntoOwned<'a> for ListRef<'a, C> where C::Owned: Clone, { @@ -55,7 +55,7 @@ where } #[derive(Debug)] -struct ListRegion { +struct ListRegion { indexes: Vec<(C::Index, Option)>, inner: C, } @@ -69,29 +69,35 @@ impl Default for ListRegion { } } -impl Region for ListRegion +impl ReadRegion for ListRegion where - C::Owned: Clone, + R::Owned: Clone, + R: ReadRegion, { - type Owned = List; - type ReadItem<'a> = ListRef<'a, C> where C: 'a; + type Owned = List; + type ReadItem<'a> = ListRef<'a, R> where R: 'a; type Index = usize; + fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { + let (inner_index, continuation) = self.indexes[index]; + ListRef(Ok((self, inner_index, continuation))) + } +} + +impl Region for ListRegion +where + R::Owned: Clone, +{ fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where Self: 'a, { Self { indexes: Vec::with_capacity(regions.clone().map(|r| r.indexes.len()).sum()), - inner: C::merge_regions(regions.map(|r| &r.inner)), + inner: R::merge_regions(regions.map(|r| &r.inner)), } } - fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { - let (inner_index, continuation) = self.indexes[index]; - ListRef(Ok((self, inner_index, continuation))) - } - fn reserve_regions<'a, I>(&mut self, regions: I) where Self: 'a, @@ -120,12 +126,12 @@ where } } -impl Push<&List> for ListRegion +impl Push<&List> for ListRegion where - for<'a> C: Region + Push<&'a T>, - C::Owned: Clone, + for<'a> R: Region + Push<&'a T>, + R::Owned: Clone, { - fn push(&mut self, item: &List) -> as Region>::Index { + fn push(&mut self, item: &List) -> as ReadRegion>::Index { let inner_index = self.inner.push(&item.0); let continuation = item.1.as_deref().map(|next| self.push(next)); self.indexes.push((inner_index, continuation));