Skip to content

Commit

Permalink
WIP to think about ownership
Browse files Browse the repository at this point in the history
Signed-off-by: Moritz Hoffmann <[email protected]>
  • Loading branch information
antiguru committed May 25, 2024
1 parent 1b1bc72 commit c45b49f
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/impls/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ where

#[cfg(test)]
mod tests {
use crate::{Push, Region, ReserveItems, StringRegion};
use crate::{Push, ReadToOwned, Region, ReserveItems, StringRegion};

#[test]
fn test_inner() {
Expand Down Expand Up @@ -220,4 +220,15 @@ mod tests {
assert!(cap > 0);
assert!(cnt > 0);
}

#[test]
fn owned() {
let mut r = <StringRegion>::default();

let idx = r.push("abc");
let reference = r.index(idx);
let owned = reference.read_to_owned();
let idx = r.push(owned);
assert_eq!("abc", r.index(idx));
}
}
65 changes: 65 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,35 @@ impl<R: Region + Clone> Clone for FlatStack<R> {
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
pub struct CopyIter<I>(pub I);

/// Conversion of references to owned data. Similar to [`ToOwned`], but without the requirement
/// that target can be borrowed to self.
///
/// The clumsy names originate from `to_owned` already being in scope.
pub trait ReadToOwned {
/// The owned type. Static lifetime to indicate that the lifetime of the owned object must not
/// depend on self.
type Owned: 'static;
/// Convert self into an owned representation.
fn read_to_owned(self) -> Self::Owned;
/// Convert self into an owned representation, re-using an existing allocation.
fn read_to_owned_into(self, target: &mut Self::Owned);
}

impl<T: ToOwned + ?Sized> ReadToOwned for &T
where
T::Owned: 'static,
{
type Owned = T::Owned;

fn read_to_owned(self) -> Self::Owned {
self.to_owned()
}

fn read_to_owned_into(self, target: &mut Self::Owned) {
self.clone_into(target);
}
}

#[cfg(test)]
mod tests {
use crate::impls::deduplicate::{CollapseSequence, ConsecutiveOffsetPairs};
Expand Down Expand Up @@ -393,6 +422,26 @@ mod tests {
hobbies: <<Vec<String> as Containerized>::Region as Region>::ReadItem<'a>,
}

impl ReadToOwned for PersonRef<'_> {
type Owned = Person;
fn read_to_owned(self) -> Person {
Person {
name: self.name.to_string(),
age: self.age,
hobbies: self.hobbies.iter().map(|s| s.to_string()).collect(),
}
}
fn read_to_owned_into(self, target: &mut Person) {
target.name.clear();
target.name.push_str(self.name);
target.age = self.age;
target.hobbies.clear();
target
.hobbies
.extend(self.hobbies.iter().map(str::to_string));
}
}

impl Region for PersonRegion {
type ReadItem<'a> = PersonRef<'a> where Self: 'a;
type Index = (
Expand Down Expand Up @@ -681,4 +730,20 @@ mod tests {
c.copy([[[vec![[&1; 1]; 1]; 1]; 1]; 1]);
c.copy([[&vec![[[&1; 1]; 1]; 1]; 1]; 1]);
}

fn owned_roundtrip<R>(region: &mut R, index: R::Index)
where
for<'a> R: Region + Push<<<R as Region>::ReadItem<'a> as ReadToOwned>::Owned>,
for<'a> R::ReadItem<'a>: ReadToOwned,
{
let item = region.index(index).read_to_owned();
region.push(item);
}

#[test]
fn test_owned() {
let mut c = <StringRegion>::default();
let index = c.push("abc".to_string());
owned_roundtrip(&mut c, index);

Check failure on line 747 in src/lib.rs

View workflow job for this annotation

GitHub Actions / cargo test on ubuntu, rust 1.65

the trait bound `for<'a> <_ as Region>::ReadItem<'a>: ReadToOwned` is not satisfied

Check failure on line 747 in src/lib.rs

View workflow job for this annotation

GitHub Actions / cargo test on macos, rust 1.65

the trait bound `for<'a> <_ as Region>::ReadItem<'a>: ReadToOwned` is not satisfied
}
}

0 comments on commit c45b49f

Please sign in to comment.