Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Sajjon committed Dec 16, 2023
1 parent f9da7dc commit c03d872
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 98 deletions.
13 changes: 13 additions & 0 deletions identified_vec/src/is_identifiable_vec.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::conflict_resolution_choice::ConflictResolutionChoice;
use crate::Error;
use crate::IdentifiedVecIterator;
use std::fmt::Debug;
use std::hash::Hash;

Expand Down Expand Up @@ -250,4 +251,16 @@ where
fn remove_at_offsets<It>(&mut self, offsets: It)
where
It: IntoIterator<Item = usize>;

/// Try append a new member to the end of the `identified_vec`, if the `identified_vec` already contains the element a Error will be returned.
///
/// - Parameter item: The element to add to the `identified_vec`.
/// - Returns: Either a Ok() with a pair `(inserted, index)`, where `inserted` is a Boolean value indicating whether
/// the operation added a new element, and `index` is the index of `item` in the resulting
/// `identified_vec`. If the given ID pre-exists within the collection the function call returns `Error::ElementWithSameIDFound`.
/// - Complexity: The operation is expected to perform O(1) copy, hash, and compare operations on
/// the `ID` type, if it implements high-quality hashing.
fn try_append_new(&mut self, element: Element) -> Result<(bool, usize), Error>;

fn iter(&self) -> IdentifiedVecIterator<ID, Element>;
}
17 changes: 15 additions & 2 deletions identified_vec/src/is_identified_vec_via.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::conflict_resolution_choice::ConflictResolutionChoice;
use crate::vec::ItemsCloned;
use crate::{
Error, Identifiable, IdentifiedVecOf, IsIdentifiableVec, IsIdentifiableVecOf, ItemsCloned,
Error, Identifiable, IdentifiedVecIterator, IdentifiedVecOf, IsIdentifiableVec,
IsIdentifiableVecOf,
};

/// https://stackoverflow.com/a/66537661/1311272
pub trait ViaMarker {}

pub trait IsIdentifiableVecOfVia<Element>: IsIdentifiableVecOf<Element> + ViaMarker
pub trait IsIdentifiableVecOfVia<Element>:
IsIdentifiableVecOf<Element> + IntoIterator<Item = Element> + ViaMarker
where
Element: Identifiable,
{
Expand Down Expand Up @@ -174,6 +177,11 @@ where
self.via_mut().update_with(id, mutate)
}

#[inline]
fn try_append_new(&mut self, element: Element) -> Result<(bool, usize), Error> {
self.via_mut().try_append_new(element)
}

/////////////
// Remove //
/////////////
Expand All @@ -199,4 +207,9 @@ where
{
self.via_mut().remove_at_offsets(offsets)
}

#[inline]
fn iter(&self) -> IdentifiedVecIterator<<Element as Identifiable>::ID, Element> {
self.via().iter()
}
}
4 changes: 4 additions & 0 deletions identified_vec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@
mod conflict_resolution_choice;
mod errors;
mod identifiable_trait;
mod identified_vec_into_iterator;
mod identified_vec_iterator;
mod is_identifiable_vec;
mod is_identifiable_vec_of;
mod is_identified_vec_via;
Expand All @@ -129,6 +131,8 @@ mod vec_of;
pub mod identified_vec {
//! A collection of unique identifiable elements which retains **insertion** order.
pub use crate::conflict_resolution_choice::*;
pub use crate::identified_vec_into_iterator::*;
pub use crate::identified_vec_iterator::*;
pub use crate::is_identifiable_vec::*;
pub use crate::vec::*;
}
Expand Down
115 changes: 27 additions & 88 deletions identified_vec/src/vec.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::conflict_resolution_choice::ConflictResolutionChoice;
use crate::errors::Error;
use crate::identified_vec_into_iterator::IdentifiedVecIntoIterator;
use crate::identified_vec_iterator::IdentifiedVecIterator;
use std::collections::HashMap;
use std::fmt::{Debug, Display};
use std::hash::{Hash, Hasher};
Expand Down Expand Up @@ -644,6 +646,30 @@ where
internal_offset += 1;
})
}

/// Try append a new member to the end of the `identified_vec`, if the `identified_vec` already contains the element a Error will be returned.
///
/// - Parameter item: The element to add to the `identified_vec`.
/// - Returns: Either a Ok() with a pair `(inserted, index)`, where `inserted` is a Boolean value indicating whether
/// the operation added a new element, and `index` is the index of `item` in the resulting
/// `identified_vec`. If the given ID pre-exists within the collection the function call returns `Error::ElementWithSameIDFound`.
/// - Complexity: The operation is expected to perform O(1) copy, hash, and compare operations on
/// the `ID` type, if it implements high-quality hashing.
#[inline]
fn try_append_new(&mut self, element: E) -> Result<(bool, usize), Error> {
let id = self.id(&element);

if self.contains_id(&id) {
return Err(Error::ElementWithSameIDFound(format!("{:#?}", id)));
}

Ok(self.append(element))
}

#[inline]
fn iter(&self) -> IdentifiedVecIterator<I, E> {
IdentifiedVecIterator::new(self)
}
}

pub trait ItemsCloned<Element>
Expand Down Expand Up @@ -671,67 +697,6 @@ where
}
}

/// An iterator over the items of an `IdentifiedVec`.
pub struct IdentifiedVecIterator<'a, I, E>
where
I: Eq + Hash + Clone + Debug,
{
identified_vec: &'a IdentifiedVec<I, E>,
index: usize,
}

impl<'a, I, E> Iterator for IdentifiedVecIterator<'a, I, E>
where
I: Eq + Hash + Clone + Debug,
{
type Item = &'a E;

fn next(&mut self) -> Option<Self::Item> {
if self.index < self.identified_vec.len() {
let id = Some(&self.identified_vec.order[self.index]).unwrap();
self.index += 1;
return self.identified_vec.get(id);
} else {
None
}
}
}

impl<I, E> IdentifiedVec<I, E>
where
I: Eq + Hash + Clone + Debug,
{
pub fn iter(&self) -> IdentifiedVecIterator<I, E> {
IdentifiedVecIterator {
identified_vec: self,
index: 0,
}
}
}

/// An owning iterator over the items of an `IdentifiedVec`.
pub struct IdentifiedVecIntoIterator<I, E>
where
I: Eq + Hash + Clone + Debug,
{
identified_vec: IdentifiedVec<I, E>,
}

impl<I, E> Iterator for IdentifiedVecIntoIterator<I, E>
where
I: Eq + Hash + Clone + Debug,
{
type Item = E;

fn next(&mut self) -> Option<Self::Item> {
if self.identified_vec.len() == 0 {
return None;
}
let result = self.identified_vec.remove_at(0);
Some(result)
}
}

impl<I, E> IntoIterator for IdentifiedVec<I, E>
where
I: Eq + Hash + Clone + Debug,
Expand All @@ -740,9 +705,7 @@ where
type IntoIter = IdentifiedVecIntoIterator<I, E>;

fn into_iter(self) -> Self::IntoIter {
Self::IntoIter {
identified_vec: self,
}
Self::IntoIter::new(self)
}
}

Expand Down Expand Up @@ -912,27 +875,3 @@ where
Ok(self.append(element))
}
}

impl<ID, Element> IdentifiedVec<ID, Element>
where
ID: Eq + Hash + Clone + Debug,
{
/// Try append a new member to the end of the `identified_vec`, if the `identified_vec` already contains the element a Error will be returned.
///
/// - Parameter item: The element to add to the `identified_vec`.
/// - Returns: Either a Ok() with a pair `(inserted, index)`, where `inserted` is a Boolean value indicating whether
/// the operation added a new element, and `index` is the index of `item` in the resulting
/// `identified_vec`. If the given ID pre-exists within the collection the function call returns `Error::ElementWithSameIDFound`.
/// - Complexity: The operation is expected to perform O(1) copy, hash, and compare operations on
/// the `ID` type, if it implements high-quality hashing.
#[inline]
pub fn try_append_new(&mut self, element: Element) -> Result<(bool, usize), Error> {
let id = self.id(&element);

if self.contains_id(&id) {
return Err(Error::ElementWithSameIDFound(format!("{:#?}", id)));
}

Ok(self.append(element))
}
}
29 changes: 29 additions & 0 deletions identified_vec_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#[macro_export]
macro_rules! newtype_identified_vec {
(of: $item_ty: ty, named: $struct_name: ident) => {
use identified_vec::IdentifiedVecIntoIterator;

pub struct $struct_name(IdentifiedVecOf<$item_ty>);

impl ViaMarker for $struct_name {}
Expand All @@ -17,5 +19,32 @@ macro_rules! newtype_identified_vec {
Self(identified_vec_of)
}
}

impl IntoIterator for $struct_name {
type Item = $item_ty;
type IntoIter = IdentifiedVecIntoIterator<<$item_ty as Identifiable>::ID, $item_ty>;

fn into_iter(self) -> Self::IntoIter {
Self::IntoIter::new(self.0)
}
}

// impl<I, E> $struct_name<I, E>
// where
// I: Eq + Hash + Clone + Debug,
// {
// pub fn iter(&self) -> IdentifiedVecIterator<I, E> {
// IdentifiedVecIterator::new(self)
// }
// }

// impl IntoIterator for $struct_name {
// type Item = $item_ty;
// type IntoIter = IdentifiedVecIntoIterator<<$item_ty as Identifiable>::ID, $item_ty>;

// fn into_iter(self) -> Self::IntoIter {
// Self::IntoIter::new(self)
// }
// }
};
}
18 changes: 10 additions & 8 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl Identifiable for User {
}

type SUT = IdentifiedVecOf<u32>;
type Users = IdentifiedVecOf<User>;
newtype_identified_vec!(of: User, named: Users);

#[test]
fn new_is_empty() {
Expand Down Expand Up @@ -334,7 +334,7 @@ fn try_append_new_unique_element() {
assert_eq!(result.unwrap().1, 3);
assert_eq!(identified_vec.items(), [1, 2, 3, 4]);

let mut identified_vec: Users = IdentifiedVecOf::new();
let mut identified_vec = Users::new();
identified_vec.append(User::blob());
identified_vec.append(User::blob_jr());
identified_vec.append(User::blob_sr());
Expand All @@ -354,7 +354,7 @@ fn try_append_new_unique_element() {

#[test]
fn try_append_element_with_existing_id() {
let mut identified_vec: Users = IdentifiedVecOf::new();
let mut identified_vec = Users::new();
identified_vec.append(User::blob());
identified_vec.append(User::blob_jr());
identified_vec.append(User::blob_sr());
Expand Down Expand Up @@ -442,7 +442,7 @@ fn try_update() {
);
assert_eq!(identified_vec.items(), [1, 2, 3]);

let mut identified_vec: Users = IdentifiedVecOf::new();
let mut identified_vec = Users::new();
identified_vec.append(User::blob());
identified_vec.append(User::blob_jr());
identified_vec.append(User::blob_sr());
Expand Down Expand Up @@ -634,11 +634,13 @@ fn isid() {
Self(identified_vec_of)
}
}
impl IntoIterator for CollectionOfUsersVia {
type Item = User;

impl CollectionOfUsersVia {
#[inline]
pub fn items(&self) -> Vec<User> {
self.0.items()
type IntoIter = IdentifiedVecIntoIterator<<User as Identifiable>::ID, User>;

fn into_iter(self) -> Self::IntoIter {
todo!()
}
}

Expand Down

0 comments on commit c03d872

Please sign in to comment.