Skip to content

Commit

Permalink
try Proxy in macro to solve Serde error
Browse files Browse the repository at this point in the history
  • Loading branch information
Sajjon committed Dec 18, 2023
1 parent 99b7d22 commit c1c2318
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 21 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ serde = ["dep:serde"]
id_prim = []

[dependencies]
paste = "1.0.14"
serde = { version = "1.0.193", optional = true }
thiserror = "1.0.50"

Expand Down
59 changes: 38 additions & 21 deletions src/vec_of/newtype_identified_vec_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,48 +21,60 @@
#[macro_export]
macro_rules! newtype_identified_vec {
(of: $item_ty: ty, named: $struct_name: ident) => {
#[derive(std::fmt::Debug, Clone, Eq, PartialEq)]
pub struct $struct_name(identified_vec::IdentifiedVecOf<$item_ty>);

impl identified_vec::ViaMarker for $struct_name {}
impl identified_vec::IsIdentifiableVecOfVia<$item_ty> for $struct_name {
fn via_mut(&mut self) -> &mut identified_vec::IdentifiedVecOf<$item_ty> {
paste::paste! {
#[derive(std::fmt::Debug, Clone, Eq, PartialEq)]
pub struct [<Proxy $struct_name>]<Element: identified_vec::Identifiable>(identified_vec::IdentifiedVecOf<Element>);
}
paste::paste! {
impl<Element: identified_vec::Identifiable> identified_vec::ViaMarker for [<Proxy $struct_name>]<Element> {}
}
paste::paste! {
impl<Element: identified_vec::Identifiable> identified_vec::IsIdentifiableVecOfVia<Element> for [<Proxy $struct_name>]<Element> {

fn via_mut(&mut self) -> &mut identified_vec::IdentifiedVecOf<Element> {
&mut self.0
}

fn via(&self) -> &identified_vec::IdentifiedVecOf<$item_ty> {
fn via(&self) -> &identified_vec::IdentifiedVecOf<Element> {
&self.0
}

fn from_identified_vec_of(
identified_vec_of: identified_vec::IdentifiedVecOf<$item_ty>,
identified_vec_of: identified_vec::IdentifiedVecOf<Element>,
) -> Self {
Self(identified_vec_of)
}
}
}
paste::paste! {
impl<Element: identified_vec::Identifiable + std::fmt::Debug> std::fmt::Display for [<Proxy $struct_name>]<Element> {

impl std::fmt::Display for $struct_name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&self.0, f)
}
}
}

paste::paste! {
impl<Element: identified_vec::Identifiable> IntoIterator for [<Proxy $struct_name>]<Element> {

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

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

#[cfg(any(test, feature = "serde"))]
impl serde::Serialize for $struct_name
paste::paste! {
impl<Element: identified_vec::Identifiable> serde::Serialize for [<Proxy $struct_name>]<Element>
where
$item_ty: serde::Serialize + identified_vec::Identifiable + std::fmt::Debug + Clone,
Element: serde::Serialize + identified_vec::Identifiable + std::fmt::Debug + Clone,
{
fn serialize<S>(
&self,
Expand All @@ -74,22 +86,27 @@ macro_rules! newtype_identified_vec {
identified_vec::IdentifiedVecOf::serialize(&self.0, serializer)
}
}
}

#[cfg(any(test, feature = "serde"))]
impl<'de> serde::Deserialize<'de> for $struct_name
paste::paste! {
impl<'de, Element: identified_vec::Identifiable> serde::Deserialize<'de> for [<Proxy $struct_name>]<Element>
where
$item_ty:
Element:
serde::Deserialize<'de> + identified_vec::Identifiable + std::fmt::Debug + Clone,
{
#[cfg(not(tarpaulin_include))] // false negative
fn deserialize<D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<$struct_name, D::Error> {
) -> Result<Self, D::Error> {
let id_vec_of =
identified_vec::IdentifiedVecOf::<$item_ty>::deserialize(deserializer)?;
identified_vec::IdentifiedVecOf::<Element>::deserialize(deserializer)?;
use identified_vec::IsIdentifiableVecOfVia;
return Ok(Self::from_identified_vec_of(id_vec_of));
}
}
}

paste::paste! {
pub type $struct_name = [<Proxy $struct_name>]<$item_ty>;
}
};
}
29 changes: 29 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,3 +668,32 @@ fn test_macro() {
sut.update_or_append(User::blob_jr());
assert_eq!(sut.items(), [User::blob_sr(), User::blob_jr()]);
}

#[test]
fn macro_not_serde() {
#[derive(Eq, PartialEq, Clone, Hash, Debug)]
pub struct Foo {
id: &'static str,
value: String,
}
impl Foo {
fn with(id: &'static str, value: String) -> Self {
Self { id, value }
}
fn new() -> Self {
Self::with("id", "value".to_string())
}
}
impl Identifiable for Foo {
type ID = &'static str;

fn id(&self) -> Self::ID {
self.id
}
}

newtype_identified_vec!(of: Foo, named: Foos);
let mut sut = Foos::new();
sut.append(Foo::new());
assert_eq!(sut.len(), 1);
}

0 comments on commit c1c2318

Please sign in to comment.