Repository: not-fl3/nanoserde
Pull request #56 (2023-05-14 01:16:16)

updates to parser
Fixes many issues related to generics

not-fl3: wow, great work! 

```diff
diff --git a/derive/src/parse.rs b/derive/src/parse.rs
index 42de5d2..67d8575 100644
--- a/derive/src/parse.rs
+++ b/derive/src/parse.rs
@@ -14,14 +14,14 @@ use alloc::{format, vec};
 
 use proc_macro::{Delimiter, Group, TokenStream, TokenTree};
 
-#[derive(Debug, Clone, PartialEq, Hash, Eq)]
+#[derive(Debug, Clone)]
 pub struct Attribute {
     pub name: String,
     pub tokens: Vec<String>,
 }
 
 #[allow(dead_code)]
-#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq)]
+#[derive(Debug, Copy, Clone)]
 pub enum Visibility {
     Public,
     Crate,
@@ -29,12 +29,12 @@ pub enum Visibility {
     Private,
 }
 
-#[derive(Debug, Clone, PartialEq, Hash, Eq)]
+#[derive(Debug, Clone)]
 pub struct Lifetime {
     pub(crate) ident: String,
 }
 
-#[derive(Debug, Clone, PartialEq, Hash, Eq)]
+#[derive(Debug, Clone)]
 pub struct Field {
     pub attributes: Vec<Attribute>,
     pub vis: Visibility,
@@ -42,19 +42,19 @@ pub struct Field {
     pub ty: Type,
 }
 
-#[derive(Debug, Clone, PartialEq, Hash, Eq)]
+#[derive(Debug, Clone)]
 pub enum ConstValType {
     Value(isize),
     Named(Box<Type>),
 }
 
-#[derive(Debug, Clone, PartialEq, Hash, Eq)]
+#[derive(Debug, Clone)]
 pub enum FnType {
     Bare,
     Closure { reusable: bool, fn_mut: bool },
 }
 
-#[derive(Debug, Clone, PartialEq, Hash, Eq)]
+#[derive(Debug, Clone)]
 pub enum Category {
     Never,
     None,
@@ -96,7 +96,7 @@ pub enum Category {
 }
 
 #[allow(dead_code)]
-#[derive(Debug, Clone, PartialEq, Hash, Eq)]
+#[derive(Debug, Clone)]
 pub struct Type {
     pub ident: Category,
     pub wraps: Option<Vec<Type>>,
@@ -104,7 +104,7 @@ pub struct Type {
     pub as_other: Option<Box<Type>>,
 }
 
-#[derive(Debug, Clone, PartialEq, Hash, Eq)]
+#[derive(Debug, Clone)]
 pub enum Generic {
     ConstGeneric {
         name: String,
@@ -126,7 +126,7 @@ pub enum Generic {
     },
 }
 
-#[derive(Debug, Clone, PartialEq, Hash, Eq)]
+#[derive(Debug, Clone)]
 pub struct Struct {
     pub name: Option<String>,
     pub named: bool,
@@ -1481,25 +1481,13 @@ fn get_all_bounds<T: Iterator<Item = TokenTree> + Clone>(source: &mut Peekable<T
     for gen in ret.iter_mut() {
         match gen {
             Generic::Generic { bounds, .. } => {
-                *bounds = std::mem::take(bounds)
-                    .into_iter()
-                    .collect::<HashSet<_>>()
-                    .into_iter()
-                    .collect()
+                *bounds = std::mem::take(bounds);
             }
             Generic::Lifetime { bounds, .. } => {
-                *bounds = std::mem::take(bounds)
-                    .into_iter()
-                    .collect::<HashSet<_>>()
-                    .into_iter()
-                    .collect()
+                *bounds = std::mem::take(bounds);
             }
             Generic::WhereBounded { bounds, .. } => {
-                *bounds = std::mem::take(bounds)
-                    .into_iter()
-                    .collect::<HashSet<_>>()
-                    .into_iter()
-                    .collect()
+                *bounds = std::mem::take(bounds);
             }
             _ => (),
         }
```
<- is this `collect()` for de-duplication? removing those traits reduce compilation time by ~0.1s and reduce `/target`  space usage by 1M, also a bit less runtime allocations during the `collect()`. 

Also this   `for gen in ret.iter_mut() {` looks a little suspicios, is getting only the last value from `ret` an expected behavior?
not-fl3: > You're correct, those were not needed so far as I can tell.

got it. So maybe we can avoid that `ret` variable at all and just add to the `bounds` right away while parsing? (I did not tried and not sure if this is possible)
knickish: @not-fl3 I was able to remove that bit also, it was indeed leftover

Patch:
diff --git a/derive/src/parse.rs b/derive/src/parse.rs
index e1a5bee..6505d0d 100644
--- a/derive/src/parse.rs
+++ b/derive/src/parse.rs
@@ -1,10 +1,12 @@
-//! Very limited rust parser
+//! Very limited rust parser, taken from nanoserde
 //!
 //! https://doc.rust-lang.org/reference/expressions/struct-expr.html
 //! https://docs.rs/syn/0.15.44/syn/enum.Type.html
 //! https://ziglang.org/documentation/0.5.0/#toc-typeInfo
 
 use core::iter::Peekable;
+use std::collections::HashSet;
+use std::num::IntErrorKind;
 
 use alloc::string::{String, ToString};
 use alloc::vec::Vec;
@@ -12,22 +14,14 @@ use alloc::{format, vec};
 
 use proc_macro::{Delimiter, Group, TokenStream, TokenTree};
 
-
-#[cfg(features = "no_std")]
-use hashbrown::HashMap;
-
-#[cfg(not(features = "no_std"))]
-use std::collections::HashMap;
-
-
-#[derive(Debug)]
+#[derive(Debug, Clone)]
 pub struct Attribute {
     pub name: String,
     pub tokens: Vec<String>,
 }
 
 #[allow(dead_code)]
-#[derive(Debug)]
+#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq)]
 pub enum Visibility {
     Public,
     Crate,
@@ -35,7 +29,12 @@ pub enum Visibility {
     Private,
 }
 
-#[derive(Debug)]
+#[derive(Debug, Clone)]
+pub struct Lifetime {
+    pub(crate) ident: String,
+}
+
+#[derive(Debug, Clone)]
 pub struct Field {
     pub attributes: Vec<Attribute>,
     pub vis: Visibility,
@@ -43,36 +42,105 @@ pub struct Field {
     pub ty: Type,
 }
 
+#[derive(Debug, Clone)]
+pub enum ConstValType {
+    Value(isize),
+    Named(Box<Type>),
+}
+
+#[derive(Debug, Clone)]
+pub enum FnType {
+    Bare,
+    Closure { reusable: bool, fn_mut: bool },
+}
+
+#[derive(Debug, Clone)]
+pub enum Category {
+    Never,
+    None,
+    Array {
+        content_type: Box<Type>,
+        len: Option<ConstValType>,
+    },
+    Tuple {
+        contents: Vec<Type>,
+    },
+    Named {
+        path: String,
+    },
+    Lifetime {
+        path: String,
+    },
+    Fn {
+        category: FnType,
+        args: Option<Box<Type>>,
+        return_type: Option<Box<Type>>,
+    },
+    UnNamed,
+    Object {
+        is_dyn: bool,
+        trait_names: Vec<Box<Type>>,
+    },
+    Associated {
+        base: Box<Type>,
+        as_trait: Box<Type>,
+        associated: Box<Type>,
+    },
+    AssociatedBound {
+        associated: String,
+        is: Box<Type>,
+    },
+    AnonymousStruct {
+        contents: Struct,
+    },
+}
+
 #[allow(dead_code)]
 #[derive(Debug, Clone)]
 pub struct Type {
-    pub is_option: bool,
-    pub path: String,
+    pub ident: Category,
+    pub wraps: Option<Vec<Type>>,
+    pub ref_type: Option<Option<Lifetime>>,
+    pub as_other: Option<Box<Type>>,
 }
 
-#[derive(Debug)]
-pub struct Struct {
-    pub name: String,
-    pub named: bool,
-    pub fields: Vec<Field>,
-    pub attributes: Vec<Attribute>,
-    pub generics: HashMap<String, String>
+#[derive(Debug, Clone)]
+pub enum Generic {
+    ConstGeneric {
+        name: String,
+        _type: Type,
+        default: Option<ConstValType>,
+    },
+    Generic {
+        name: String,
+        default: Option<Type>,
+        bounds: Vec<Type>,
+    },
+    Lifetime {
+        name: String,
+        bounds: Vec<Lifetime>,
+    },
+    WhereBounded {
+        name: String,
+        bounds: Vec<Type>,
+    },
 }
 
-#[derive(Debug)]
-pub struct EnumVariant {
-    pub name: String,
+#[derive(Debug, Clone)]
+pub struct Struct {
+    pub name: Option<String>,
     pub named: bool,
     pub fields: Vec<Field>,
     pub attributes: Vec<Attribute>,
+    pub generics: Vec<Generic>,
 }
 
 #[derive(Debug)]
 pub struct Enum {
     pub name: String,
-    pub variants: Vec<EnumVariant>,
+    pub variants: Vec<Field>,
     pub attributes: Vec<Attribute>,
-    pub generics: HashMap<String, String>
+    pub generics: Vec<Generic>,
 }
 
 #[allow(dead_code)]
@@ -82,10 +150,14 @@ pub enum Data {
     Union(()),
 }
 
+#[allow(dead_code)]
 impl Data {
     pub fn name(&self) -> &str {
         match self {
-            Data::Struct(Struct { name, .. }) => name.as_str(),
+            Data::Struct(Struct { name, .. }) => match name {
+                Some(name) => name.as_str(),
+                None => "",
+            },
             Data::Enum(Enum { name, .. }) => name.as_str(),
             _ => unimplemented!(),
         }
@@ -100,6 +172,290 @@ impl Data {
     }
 }
 
+impl Generic {
+    pub fn full(&self) -> String {
+        match &self {
+            Generic::ConstGeneric { name, .. } => name.clone(),
+            Generic::Generic { name, .. } => name.clone(),
+            Generic::Lifetime { name, .. } => name.clone(),
+            Generic::WhereBounded { name, .. } => name.clone(),
+        }
+    }
+
+    fn lifetime_prefix(&self) -> &str {
+        match &self {
+            Generic::Lifetime { .. } => "\'",
+            _ => "",
+        }
+    }
+
+    fn const_prefix(&self) -> &str {
+        match &self {
+            Generic::ConstGeneric { .. } => "const ",
+            _ => "",
+        }
+    }
+
+    pub fn ident_only(&self) -> String {
+        format!("{}{}", self.lifetime_prefix(), self.full())
+    }
+
+    pub fn full_with_const(&self, extra_bounds: &[&str], bounds: bool) -> String {
+        let bounds = match (bounds, &self) {
+            (true, Generic::Lifetime { .. }) => self.get_bounds().join(" + "),
+            (true, _) => {
+                let mut bounds = self.get_bounds().join(" + ");
+                if !extra_bounds.is_empty() {
+                    if bounds.is_empty() {
+                        bounds = extra_bounds.join(" + ")
+                    } else {
+                        bounds = format!("{} + {}", bounds, extra_bounds.join(" + "));
+                    }
+                }
+                bounds
+            }
+            (_, Generic::ConstGeneric { .. }) => self.get_bounds().join(" + "),
+            (false, _) => String::new(),
+        };
+        match bounds.is_empty() {
+            true => format!(
+                "{}{}{}:",
+                self.const_prefix(),
+                self.lifetime_prefix(),
+                self.full()
+            ),
+            false => format!(
+                "{}{}{}: {}",
+                self.const_prefix(),
+                self.lifetime_prefix(),
+                self.full(),
+                bounds
+            ),
+        }
+    }
+
+    #[allow(unused)]
+    pub fn full_with_const_and_default(&self, extra_bounds: &[&str], bounds: bool) -> String {
+        let bounds = match (bounds, &self) {
+            (true, Generic::Lifetime { .. }) => String::new(),
+            (true, _) | (false, Generic::ConstGeneric { .. }) => {
+                let mut bounds = self.get_bounds().join(" + ");
+                if !extra_bounds.is_empty() {
+                    if bounds.is_empty() {
+                        bounds = extra_bounds.join(" + ")
+                    } else {
+                        bounds = vec![bounds, extra_bounds.join(" + ")].join(" + ")
+                    }
+                }
+                bounds
+            }
+            (false, _) => String::new(),
+        };
+        match bounds.is_empty() {
+            true => format!(
+                "{}{}{}{}",
+                self.const_prefix(),
+                self.lifetime_prefix(),
+                self.full(),
+                self.get_default()
+            ),
+            false => format!(
+                "{}{}{}: {}{}",
+                self.const_prefix(),
+                self.lifetime_prefix(),
+                self.full(),
+                bounds,
+                self.get_default()
+            ),
+        }
+    }
+
+    fn get_bounds(&self) -> Vec<String> {
+        match &self {
+            Generic::ConstGeneric { _type, .. } => vec![format!("{}", _type.full())],
+            Generic::Generic { bounds, .. } => bounds.iter().map(Type::full).collect(),
+            Generic::Lifetime { bounds, .. } => {
+                bounds.iter().map(|x| format!("'{}", x.ident)).collect()
+            }
+            Generic::WhereBounded { bounds, .. } => bounds.iter().map(Type::full).collect(),
+        }
+    }
+
+    fn get_default(&self) -> String {
+        match &self {
+            Generic::ConstGeneric {
+                default: Some(def), ..
+            } => match def {
+                ConstValType::Value(v) => format!("= {}", v),
+                ConstValType::Named(v) => format!("= {}", v.full()),
+            },
+            Generic::Generic {
+                default: Some(def), ..
+            } => format!("= {}", def.full()),
+            _ => String::new(),
+        }
+    }
+}
+
+impl Category {
+    pub fn path(&self, parent: &Type, no_ref: bool) -> String {
+        #[allow(unused)]
+        let mut holder: Option<Type> = None;
+        let parent = match no_ref {
+            true => {
+                holder = Some(parent.clone().set_ref_type(None));
+                holder.as_ref().unwrap()
+            }
+            false => parent,
+        };
+        match self {
+            Category::Array { content_type, len } => match len {
+                Some(ConstValType::Value(val)) => format!("[{};{}]", content_type.full(), val),
+                Some(ConstValType::Named(const_gen)) => match &const_gen.as_other {
+                    Some(as_type) => format!(
+                        "[{};{} as {}]",
+                        content_type.full(),
+                        const_gen.full(),
+                        as_type.full()
+                    ),
+                    None => format!("[{};{}]", content_type.full(), const_gen.full()),
+                },
+                None => format!("[{}]", content_type.full()),
+            },
+            Category::Tuple { contents } => format!(
+                "({})",
+                contents
+                    .iter()
+                    .map(Type::full)
+                    .collect::<Vec<_>>()
+                    .join(", ")
+            ),
+            Category::Named { path } => path.clone(),
+            Category::UnNamed => String::default(),
+            Category::Object {
+                is_dyn,
+                trait_names,
+            } => match is_dyn {
+                true => format!(
+                    "dyn {}",
+                    trait_names
+                        .iter()
+                        .map(|x| x.full())
+                        .collect::<Vec<_>>()
+                        .join(" + ")
+                ),
+                false => format!(
+                    "impl {}",
+                    trait_names
+                        .iter()
+                        .map(|x| x.full())
+                        .collect::<Vec<_>>()
+                        .join(" + ")
+                ),
+            },
+            Category::Associated {
+                base,
+                as_trait,
+                associated,
+            } => format!(
+                "<{} as {}>::{}",
+                base.full(),
+                as_trait.full(),
+                associated.full()
+            ),
+            Category::AssociatedBound { associated, is } => format!(
+                "{}<{}= {}>",
+                associated,
+                parent.wraps.as_ref().unwrap()[0].full(),
+                is.full()
+            ),
+            Category::Lifetime { path } => format!("\'{}", path),
+            Category::Fn {
+                category,
+                args,
+                return_type,
+            } => {
+                let arg_str = args.as_ref().map(|x| x.full()).unwrap_or_default();
+                let return_str = return_type
+                    .as_ref()
+                    .map(|x| format!(" -> {}", x.full()))
+                    .unwrap_or_default();
+                match category {
+                    FnType::Bare => format!("fn({}){}", arg_str, return_str),
+                    FnType::Closure { reusable, fn_mut } => match fn_mut {
+                        true => format!("FnMut({}){}", arg_str, return_str),
+                        false => match reusable {
+                            true => format!("Fn({}){}", arg_str, return_str),
+                            false => format!("FnOnce({}){}", arg_str, return_str),
+                        },
+                    },
+                }
+            }
+            Category::Never => String::from("!"),
+            Category::None => String::new(),
+            Category::AnonymousStruct {
+                contents: Struct { name, fields, .. },
+            } => {
+                let mut l = name.as_ref().map_or(String::new(), |x| x.clone());
+                l!(l, "{\n");
+                for field in fields.iter() {
+                    l!(
+                        l,
+                        "\t{}: {}\n",
+                        field.field_name.as_ref().expect("field must have name"),
+                        field.ty.full()
+                    );
+                }
+                l!(l, "}\n");
+                l
+            }
+        }
+    }
+}
+
+impl Type {
+    pub fn base(&self) -> String {
+        let mut base = match &self.ref_type {
+            Some(inner) => match inner {
+                Some(ident) => format!("&\'{} ", ident.ident),
+                None => String::from("& "),
+            },
+            None => String::default(),
+        };
+        base.push_str(&self.ident.path(&self, false));
+        base
+    }
+
+    pub fn full(&self) -> String {
+        let mut base = match &self.ref_type {
+            Some(inner) => match inner {
+                Some(ident) => format!("&\'{} ", ident.ident),
+                None => String::from("& "),
+            },
+            None => String::default(),
+        };
+        base.push_str(&self.ident.path(&self, false));
+        if let (Some(wrapped), Category::Named { .. }) = (&self.wraps, &self.ident) {
+            base.push('<');
+            base.push_str(
+                wrapped
+                    .into_iter()
+                    .map(|x| x.full())
+                    .collect::<Vec<_>>()
+                    .join(",")
+                    .as_str(),
+            );
+            base.push('>');
+        }
+        base
+    }
+
+    pub fn set_ref_type(mut self, ref_type: Option<Option<Lifetime>>) -> Self {
+        self.ref_type = ref_type;
+        self
+    }
+}
+
 pub fn next_visibility_modifier(
     source: &mut Peekable<impl Iterator<Item = TokenTree>>,
 ) -> Option<String> {
@@ -192,31 +548,374 @@ pub fn next_group(source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> Opt
     }
 }
 
-// pub fn debug_current_token(source: &mut Peekable<impl Iterator<Item = TokenTree>>) {
-//     println!("{:?}", source.peek());
-// }
+pub fn _debug_current_token(source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> String {
+    format!("{:?}", source.peek())
+}
 
-fn next_type<T: Iterator<Item = TokenTree>>(mut source: &mut Peekable<T>, generic_typenames: &HashMap<String, String> ) -> Option<Type> {
-    let group = next_group(&mut source);
-    if group.is_some() {
-        let mut group = group.unwrap().stream().into_iter().peekable();
+pub fn next_lifetime<T: Iterator<Item = TokenTree>>(source: &mut Peekable<T>) -> Option<Lifetime> {
+    let Some (TokenTree::Punct(punct)) = source.peek() else { return None; };
+    let '\'' = punct.as_char() else { return None; };
+
+    let _ = source.next();
+    Some(Lifetime {
+        ident: next_ident(source).expect("must be an identifier after a single quote"),
+    })
+}
 
-        let mut tuple_type = Type {
-            is_option: false,
-            path: "".to_string(),
+fn next_type<T: Iterator<Item = TokenTree> + Clone>(mut source: &mut Peekable<T>) -> Option<Type> {
+    fn as_associated_definition<T: Iterator<Item = TokenTree> + Clone>(
+        source: &mut Peekable<T>,
+    ) -> Option<Type> {
+        if let Some(TokenTree::Punct(punct)) = source.peek() {
+            if punct.as_char() == '=' {
+                source.next();
+                let ty = next_type(source).expect("Missing type after \"as\"");
+                return Some(ty);
+            }
+        }
+        None
+    }
+    fn as_other_type<T: Iterator<Item = TokenTree> + Clone>(
+        source: &mut Peekable<T>,
+    ) -> Option<Type> {
+        if let Some(TokenTree::Ident(ident)) = source.peek() {
+            if ident.to_string() == "as" {
+                source.next();
+                let ty = next_type(source).expect("Missing type after \"as\"");
+                return Some(ty);
+            }
+        }
+        None
+    }
+    pub fn next_array<T: Iterator<Item = TokenTree> + Clone>(
+        mut source: &mut Peekable<T>,
+    ) -> Option<Type> {
+        let next = next_type(&mut source).expect("Must be type after array declaration");
+
+        let Some(_) = next_exact_punct(&mut source, ";") else {
+            // This is an unbounded array, legal at end for unsized types
+            return Some(Type { ident: Category::Array { content_type: Box::new(next.clone()), len: None }, wraps: Some(vec![next]), ref_type: None, as_other: None })
         };
 
-        while let Some(next_ty) = next_type(&mut group, generic_typenames) {
-            tuple_type.path.push_str(&format!("{}, ", next_ty.path));
+        //need to cover both the const generic and literal case
+        let len = source.peek().unwrap().to_string();
+        match len.parse::<usize>() {
+            Ok(val) => Some(Type {
+                ident: Category::Array {
+                    content_type: Box::new(next.clone()),
+                    len: Some(ConstValType::Value(val as isize)),
+                },
+                wraps: Some(vec![next]),
+                ref_type: None,
+                as_other: None,
+            }),
+            Err(err) if err.kind() == &IntErrorKind::Zero => Some(Type {
+                ident: Category::Array {
+                    content_type: Box::new(next.clone()),
+                    len: Some(ConstValType::Value(0)),
+                },
+                wraps: Some(vec![next]),
+                ref_type: None,
+                as_other: None,
+            }),
+            _ => Some(Type {
+                ident: Category::Array {
+                    content_type: Box::new(next.clone()),
+                    len: Some(ConstValType::Named(Box::new(next_type(source).unwrap()))),
+                },
+                wraps: Some(vec![next]),
+                ref_type: None,
+                as_other: None,
+            }),
         }
+    }
+
+    pub fn next_tuple<T: Iterator<Item = TokenTree> + Clone>(
+        source: &mut Peekable<T>,
+    ) -> Option<Type> {
+        let mut wraps = vec![];
+        let mut path = "(".to_owned();
+        while let Some(next_ty) = next_type(source) {
+            wraps.push(next_ty.clone());
+            path.push_str(&format!("{}", next_ty.full()));
+            if next_exact_punct(source, ",").is_none() {
+                break;
+            }
+            path.push(',')
+        }
+        path.push(')');
+
+        let tuple_type = Type {
+            ident: Category::Tuple {
+                contents: wraps.clone(),
+            },
+            wraps: Some(wraps),
+            ref_type: None,
+            as_other: None,
+        };
 
         return Some(tuple_type);
     }
 
+    pub fn next_function_like<T: Iterator<Item = TokenTree> + Clone>(
+        source: &mut Peekable<T>,
+    ) -> Option<Type> {
+        pub fn next_return_type<T: Iterator<Item = TokenTree> + Clone>(
+            source: &mut Peekable<T>,
+        ) -> Option<Type> {
+            let mut tmp = source.clone();
+            let (Some(_), Some(_)) = ( next_exact_punct(&mut tmp, "-"),  next_exact_punct(&mut tmp, ">")) else {
+                return None;
+            };
+            drop(tmp);
+            let _ = (source.next(), source.next());
+            Some(next_type(source).expect("Missing return type"))
+        }
+
+        pub fn next_closure<T: Iterator<Item = TokenTree> + Clone>(
+            source: &mut Peekable<T>,
+            reusable: bool,
+            fn_mut: bool,
+        ) -> Type {
+            let args = next_group(source)
+                .map(|group| {
+                    next_type(&mut group.stream().into_iter().peekable()).expect("Missing args")
+                })
+                .map(Box::new);
+
+            let ret = next_return_type(source).map(Box::new);
+
+            let wraps = if args.as_ref().map(|x| x.wraps.as_ref()).is_some()
+                || ret.as_ref().map(|x| x.wraps.as_ref()).is_some()
+            {
+                let mut base = ret
+                    .iter()
+                    .filter_map(|x| x.wraps.as_ref())
+                    .cloned()
+                    .flatten()
+                    .collect::<Vec<Type>>();
+                base.extend(
+                    args.iter()
+                        .filter_map(|x| x.wraps.as_ref())
+                        .cloned()
+                        .flatten(),
+                );
+                Some(base)
+            } else {
+                None
+            };
+            Type {
+                ident: Category::Fn {
+                    category: FnType::Closure { reusable, fn_mut },
+                    args,
+                    return_type: ret,
+                },
+                wraps,
+                ref_type: None,
+                as_other: None,
+            }
+        }
+
+        let Some(TokenTree::Ident(ident)) = source.peek().clone() else {
+            return None;
+        };
+        let true = matches!(ident.to_string().as_str(), "fn" | "FnOnce" | "FnMut" | "Fn") else {
+            return None;
+       };
+        let tok_str = source.next().unwrap().to_string();
+
+        match tok_str.as_str() {
+            "fn" => {
+                let args = next_type(
+                    &mut next_group(source)
+                        .expect("Missing args group")
+                        .stream()
+                        .into_iter()
+                        .peekable(),
+                )
+                .map(Box::new)
+                .expect("Missing args");
+                let ret = next_return_type(source).map(Box::new);
+
+                let wraps =
+                    if args.wraps.is_some() || ret.as_ref().map(|x| x.wraps.as_ref()).is_some() {
+                        let mut base = ret
+                            .iter()
+                            .filter_map(|x| x.wraps.as_ref())
+                            .cloned()
+                            .flatten()
+                            .collect::<Vec<Type>>();
+                        base.extend_from_slice(args.wraps.clone().unwrap_or_default().as_ref());
+                        Some(base)
+                    } else {
+                        None
+                    };
+                Some(Type {
+                    ident: Category::Fn {
+                        category: FnType::Bare,
+                        args: Some(args),
+                        return_type: ret,
+                    },
+                    wraps,
+                    ref_type: None,
+                    as_other: None,
+                })
+            }
+            "Fn" => Some(next_closure(source, true, false)),
+            "FnMut" => Some(next_closure(source, true, true)),
+            "FnOnce" => Some(next_closure(source, false, false)),
+            _ => None,
+        }
+    }
+
+    pub fn next_object<T: Iterator<Item = TokenTree> + Clone>(
+        source: &mut Peekable<T>,
+    ) -> Option<Type> {
+        let Some(TokenTree::Ident(ident)) = source.peek() else {
+            return None
+        };
+        let true = matches!(ident.to_string().as_str(), "impl" | "dyn") else {
+             return None;
+        };
+        match source.next().unwrap().to_string().as_str() {
+            "impl" => {
+                let mut ident_types = vec![Box::new(
+                    next_type(source).expect("impl must be followed by trait"),
+                )];
+                while let Some(_) = next_exact_punct(source, "+") {
+                    ident_types.push(Box::new(
+                        next_type(source).expect("impl must be followed by trait"),
+                    ))
+                }
+                let ref_type = ident_types[0].ref_type.clone();
+                let as_other = ident_types[0].as_other.clone();
+                let wraps = ident_types[0].wraps.clone();
+                Some(Type {
+                    ident: Category::Object {
+                        is_dyn: false,
+                        trait_names: ident_types,
+                    },
+                    wraps,
+                    ref_type,
+                    as_other,
+                })
+            }
+            "dyn" => {
+                let mut ident_types = vec![Box::new(
+                    next_type(source).expect("impl must be followed by trait"),
+                )];
+                while let Some(_) = next_exact_punct(source, "+") {
+                    ident_types.push(Box::new(
+                        next_type(source).expect("impl must be followed by trait"),
+                    ))
+                }
+                let ref_type = ident_types[0].ref_type.clone();
+                let as_other = ident_types[0].as_other.clone();
+                let wraps = ident_types[0].wraps.clone();
+                Some(Type {
+                    ident: Category::Object {
+                        is_dyn: true,
+                        trait_names: ident_types,
+                    },
+                    wraps,
+                    ref_type,
+                    as_other,
+                })
+            }
+            _ => None,
+        }
+    }
+
+    //
+    //
+
+    if let Some(_) = next_exact_punct(&mut source, ",") {
+        return None;
+    };
+
+    if let Some(_) = next_exact_punct(&mut source, "!") {
+        return Some(Type {
+            ident: Category::Never,
+            wraps: None,
+            ref_type: None,
+            as_other: None,
+        });
+    };
+
+    let None = next_exact_punct(source, "\'") else {
+        return Some(Type{ ident: Category::Lifetime { path: next_ident(source).expect("Need lifetime name") }, wraps: None, ref_type: None, as_other: None })
+    };
+
+    let ref_type = match next_exact_punct(&mut source, "&") {
+        Some(_) => Some(next_lifetime(source)),
+        None => None,
+    };
+
+    if let Some(group) = next_group(&mut source.clone()) {
+        match group.delimiter() {
+            Delimiter::Bracket => {
+                let mut group_stream = next_group(&mut source)
+                    .unwrap()
+                    .stream()
+                    .into_iter()
+                    .peekable();
+                return next_array(&mut group_stream).map(|x| x.set_ref_type(ref_type));
+            }
+            Delimiter::Parenthesis => {
+                let mut group_stream = next_group(&mut source)
+                    .unwrap()
+                    .stream()
+                    .into_iter()
+                    .peekable();
+                return next_tuple(&mut group_stream).map(|x| x.set_ref_type(ref_type));
+            }
+            Delimiter::Brace => {
+                let anonymous_struct = next_struct(&mut source);
+                let wraps = Some(
+                    anonymous_struct
+                        .fields
+                        .iter()
+                        .map(|x| x.ty.clone())
+                        .collect(),
+                );
+                return Some(Type {
+                    ident: Category::AnonymousStruct {
+                        contents: anonymous_struct,
+                    },
+                    wraps,
+                    ref_type,
+                    as_other: None,
+                });
+            }
+
+            _ => {
+                let mut group_stream = group.stream().into_iter().peekable();
+                _debug_current_token(&mut group_stream);
+                unimplemented!(
+                    "Unexpected token: {}",
+                    _debug_current_token(&mut group_stream)
+                )
+            }
+        }
+    }
+
+    if let Some(obj) = next_object(source) {
+        return Some(obj.set_ref_type(ref_type));
+    }
+
+    if let Some(obj) = next_function_like(source) {
+        return Some(obj.set_ref_type(ref_type));
+    }
+
     // read a path like a::b::c::d
-    let mut ty = next_ident(&mut source)?;
-    while let Some(_) = next_exact_punct(&mut source, ":") {
-        let _second_colon = next_exact_punct(&mut source, ":").expect("Expecting second :");
+    let mut ty = next_ident(&mut source).unwrap_or_default();
+    while let Some(TokenTree::Punct(_)) = source.peek() {
+        let mut tmp = source.clone();
+        let (Some(_), Some(_)) = ( next_exact_punct(&mut tmp, ":"),  next_exact_punct(&mut tmp, ":")) else {
+            break;
+        };
+        drop(tmp);
+        let _ = (source.next(), source.next()); //skip the colons
 
         let next_ident = next_ident(&mut source).expect("Expecting next path part after ::");
         ty.push_str(&format!("::{}", next_ident));
@@ -224,104 +923,194 @@ fn next_type<T: Iterator<Item = TokenTree>>(mut source: &mut Peekable<T>, generi
 
     let angel_bracket = next_exact_punct(&mut source, "<");
     if angel_bracket.is_some() {
-        let mut generic_type = next_type(source, generic_typenames).expect("Expecting generic argument");
+        if ty.is_empty() {
+            let ty = next_type(source).expect("Need a base type before 'as'");
+
+            assert!(
+                matches!(ty.ident, Category::Named { .. }),
+                "need a named type here"
+            );
+
+            //skip the close bracket and two colons that must follow to get an associated type
+            assert_eq!(Some(">".to_owned()), next_exact_punct(source, ">"));
+            assert_eq!(
+                (Some(":".to_owned()), Some(":".to_owned())),
+                (
+                    next_exact_punct(&mut source, ":"),
+                    next_exact_punct(&mut source, ":")
+                )
+            );
+            let associated =
+                next_type(source).expect("Must be an associated type name after the trait");
+
+            let as_trait = ty
+                .as_other
+                .clone()
+                .expect("Must be an as_other for an associated type");
+
+            return Some(Type {
+                ident: Category::Associated {
+                    base: Box::new(ty.clone()),
+                    as_trait,
+                    associated: Box::new(associated),
+                },
+                wraps: ty.wraps,
+                ref_type: ref_type,
+                as_other: None,
+            });
+        }
+
+        let mut generics =
+            vec![next_type(source).expect("Expecting at least one generic argument")];
         while let Some(_comma) = next_exact_punct(&mut source, ",") {
-            let next_ty = next_type(source, generic_typenames).expect("Expecting generic argument");
-            generic_type.path.push_str(&format!(", {}", next_ty.path));
+            generics.push(next_type(source).expect("Expecting generic argument after comma"));
+        }
+
+        let as_other = as_other_type(source).map(Box::new);
+
+        if let Some(assoc_def) = as_associated_definition(source) {
+            let _closing_bracket =
+                next_exact_punct(&mut source, ">").expect("Expecting closing generic bracket");
+            return Some(Type {
+                ident: Category::AssociatedBound {
+                    associated: ty,
+                    is: Box::new(assoc_def),
+                },
+                wraps: Some(generics),
+                ref_type,
+                as_other,
+            });
         }
 
         let _closing_bracket =
             next_exact_punct(&mut source, ">").expect("Expecting closing generic bracket");
 
-        if ty == "Option" {
+        Some(Type {
+            ident: Category::Named { path: ty },
+            wraps: Some(generics),
+            ref_type,
+            as_other,
+        })
+    } else {
+        let as_other = as_other_type(source).map(Box::new);
+        if ty.is_empty() {
             Some(Type {
-                path: generic_type.path.clone(),
-                is_option: true,
+                ident: Category::UnNamed,
+                wraps: None,
+                ref_type,
+                as_other,
             })
         } else {
             Some(Type {
-                path: format!("{}<{}>", ty, generic_type.path),
-                is_option: false,
+                ident: Category::Named { path: ty },
+                wraps: None,
+                ref_type,
+                as_other,
             })
         }
-    } else {
-        Some(Type {
-            path: ty.clone(),
-            is_option: false,
-        })
     }
 }
 
 fn next_attribute<T: Iterator<Item = TokenTree>>(
     mut source: &mut Peekable<T>,
-) -> Option<Option<Attribute>> {
+) -> Option<Option<Vec<Attribute>>> {
     // all attributes, even doc-comments, starts with "#"
     let next_attr_punct = next_punct(&mut source);
-    if let Some("#") = next_attr_punct.as_deref() {
-        let mut attr_group = next_group(&mut source)
-            .expect("Expecting attribute body")
-            .stream()
-            .into_iter()
-            .peekable();
+    let Some("#") = next_attr_punct.as_deref() else {
+        return None
+    };
 
-        let name = next_ident(&mut attr_group).expect("Attributes should start with a name");
+    let mut attr_group = next_group(&mut source)
+        .expect("Expecting attribute body")
+        .stream()
+        .into_iter()
+        .peekable();
 
-        if name != "nserde" {
-            return Some(None);
-        }
+    let name = next_ident(&mut attr_group).expect("Attributes should start with a name");
 
-        let mut args_group = next_group(&mut attr_group)
-            .expect("Expecting attribute body")
-            .stream()
-            .into_iter()
-            .peekable();
+    if name != "nserde" {
+        return Some(None);
+    }
 
-        let mut attr_tokens = vec![];
+    let mut args_group = next_group(&mut attr_group)
+        .expect("Expecting attribute body")
+        .stream()
+        .into_iter()
+        .peekable();
 
-        loop {
-            let attribute_name = next_ident(&mut args_group).expect("Expecting attribute name");
-            attr_tokens.push(attribute_name);
+    let mut attrs = vec![];
+    let mut attr_tokens = vec![];
 
-            // single-word attribute, like #[nserde(whatever)]
-            if next_eof(&mut args_group).is_some() {
+    loop {
+        let attribute_name = next_ident(&mut args_group).expect("Expecting attribute name");
+        attr_tokens.push(attribute_name);
+
+        // single-word attribute, like #[structdiff(whatever)]
+        match (
+            next_eof(&mut args_group).is_some(),
+            next_punct(&mut args_group).as_deref(),
+        ) {
+            (true, _) => {
+                attrs.push(Attribute {
+                    name: name.clone(),
+                    tokens: std::mem::take(&mut attr_tokens),
+                });
                 break;
             }
-            let _ = next_exact_punct(&mut args_group, "=")
-                .expect("Expecting = after attribute argument name");
-            let value = next_literal(&mut args_group).expect("Expecting argument value");
+            (false, Some(",")) => {
+                attrs.push(Attribute {
+                    name: name.clone(),
+                    tokens: std::mem::take(&mut attr_tokens),
+                });
+                continue;
+            }
+            (false, Some("=")) => (), // continue and get next literal
+            _ => (),
+        }
+
+        let value = next_literal(&mut args_group).expect("Expecting argument value");
 
-            attr_tokens.push(value);
+        attr_tokens.push(value.clone());
 
-            if next_eof(&mut args_group).is_some() {
+        match (
+            next_eof(&mut args_group).is_some(),
+            next_punct(&mut args_group).as_deref() == Some(","),
+        ) {
+            (true, _) => {
+                attrs.push(Attribute {
+                    name: name.clone(),
+                    tokens: std::mem::take(&mut attr_tokens),
+                });
                 break;
             }
+            (false, true) => {
+                attrs.push(Attribute {
+                    name: name.clone(),
+                    tokens: std::mem::take(&mut attr_tokens),
+                });
+            }
+            _ => {}
         }
-
-        return Some(Some(Attribute {
-            name,
-            tokens: attr_tokens,
-        }));
     }
 
-    None
+    return Some(Some(attrs));
 }
 
 fn next_attributes_list(source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> Vec<Attribute> {
     let mut attributes = vec![];
 
     while let Some(attr) = next_attribute(source) {
-        if let Some(nserde_attr) = attr {
-            attributes.push(nserde_attr);
+        if let Some(structdiff_attr) = attr {
+            attributes.extend(structdiff_attr.into_iter());
         }
     }
 
     attributes
 }
 
-fn next_fields(
-    mut body: &mut Peekable<impl Iterator<Item = TokenTree>>,
+fn next_fields<T: Iterator<Item = TokenTree> + Clone>(
+    mut body: &mut Peekable<T>,
     named: bool,
-    generic_typenames: &HashMap<String, String>
 ) -> Vec<Field> {
     let mut fields = vec![];
 
@@ -332,6 +1121,7 @@ fn next_fields(
 
         let attributes = next_attributes_list(&mut body);
         let _visibility = next_visibility_modifier(&mut body);
+
         let field_name = if named {
             let field_name = next_ident(&mut body).expect("Field name expected");
 
@@ -341,22 +1131,22 @@ fn next_fields(
             None
         };
 
-        let ty = next_type(&mut body, &generic_typenames).expect("Expected field type");
+        let ty = next_type(&mut body).expect("Expected field type");
         let _punct = next_punct(&mut body);
 
         fields.push(Field {
             attributes,
             vis: Visibility::Public,
-            field_name: field_name,
+            field_name,
             ty,
         });
     }
     fields
 }
 
-fn next_struct(mut source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> Struct {
-    let struct_name = next_ident(&mut source).expect("Unnamed structs are not supported");
-    let generic_types = get_bounds(source);
+fn next_struct<T: Iterator<Item = TokenTree> + Clone>(mut source: &mut Peekable<T>) -> Struct {
+    let struct_name = next_ident(&mut source);
+    let generics = get_all_bounds(source);
     let group = next_group(&mut source);
     // unit struct
     if group.is_none() {
@@ -368,10 +1158,10 @@ fn next_struct(mut source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> St
             fields: vec![],
             attributes: vec![],
             named: false,
-            generics: Default::default(),
+            generics,
         };
     };
-    
+
     let group = group.unwrap();
     let delimiter = group.delimiter();
     let named = match delimiter {
@@ -382,7 +1172,7 @@ fn next_struct(mut source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> St
     };
 
     let mut body = group.stream().into_iter().peekable();
-    let fields = next_fields(&mut body, named, &generic_types);
+    let fields = next_fields(&mut body, named);
 
     if named == false {
         next_exact_punct(&mut source, ";").expect("Expected ; on the end of tuple struct");
@@ -393,13 +1183,13 @@ fn next_struct(mut source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> St
         named,
         fields,
         attributes: vec![],
-        generics: generic_types
+        generics,
     }
 }
 
-fn next_enum(mut source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> Enum {
+fn next_enum<T: Iterator<Item = TokenTree> + Clone>(mut source: &mut Peekable<T>) -> Enum {
     let enum_name = next_ident(&mut source).expect("Unnamed enums are not supported");
-    let generic_types = get_bounds(source);
+    let generic_types = get_all_bounds(source);
     let group = next_group(&mut source);
     // unit enum
     if group.is_none() {
@@ -407,7 +1197,8 @@ fn next_enum(mut source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> Enum
             name: enum_name,
             variants: vec![],
             attributes: vec![],
-            generics: Default::default(),        };
+            generics: vec![],
+        };
     };
     let group = group.unwrap();
     let mut body = group.stream().into_iter().peekable();
@@ -421,33 +1212,24 @@ fn next_enum(mut source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> Enum
         let attributes = next_attributes_list(&mut body);
 
         let variant_name = next_ident(&mut body).expect("Unnamed variants are not supported");
-        let group = next_group(&mut body);
-        if group.is_none() {
-            variants.push(EnumVariant {
-                name: variant_name,
-                named: false,
-                fields: vec![],
+        let ty = next_type(&mut body);
+        let Some(ty) = ty else {
+            variants.push(Field {
+                ty: Type { ident: Category::None, wraps: None, ref_type: None, as_other: None },
                 attributes,
+                vis: Visibility::Public,
+                field_name: Some(variant_name),
             });
             let _maybe_comma = next_exact_punct(&mut body, ",");
             continue;
-        }
-        let group = group.unwrap();
-        let delimiter = group.delimiter();
-        let named = match delimiter {
-            Delimiter::Parenthesis => false,
-            Delimiter::Brace => true,
-
-            _ => panic!("Enum with unsupported delimiter"),
         };
+
         {
-            let mut body = group.stream().into_iter().peekable();
-            let fields = next_fields(&mut body, named, &generic_types);
-            variants.push(EnumVariant {
-                name: variant_name,
-                named,
-                fields,
+            variants.push(Field {
+                field_name: Some(variant_name),
+                ty: ty,
                 attributes,
+                vis: Visibility::Public,
             });
         }
         let _maybe_semicolon = next_exact_punct(&mut body, ";");
@@ -458,103 +1240,241 @@ fn next_enum(mut source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> Enum
         name: enum_name,
         variants,
         attributes: vec![],
-        generics: generic_types
+        generics: generic_types,
+    }
+}
+
+fn next_const_generic<T: Iterator<Item = TokenTree> + Clone>(
+    source: &mut Peekable<T>,
+) -> (String, Type, Option<ConstValType>) {
+    let name = source
+        .next()
+        .expect("Missing generic parameter after 'const'")
+        .to_string();
+    assert_eq!(
+        source.next().unwrap().to_string(),
+        ":",
+        "Colon should follow const generic typename"
+    );
+    let cg_type = next_type(source).expect("Missing const generic type after 'colon'");
+    if let Some(_) = next_exact_punct(source, "=") {
+        if let Ok(default_value) = source
+            .peek()
+            .expect("default should follow equal for const generic")
+            .to_string()
+            .parse::<isize>()
+        {
+            source.next();
+            (name, cg_type, Some(ConstValType::Value(default_value)))
+        } else {
+            let def =
+                next_type(source).expect("must have either a value or other const as default");
+            (name, cg_type, Some(ConstValType::Named(Box::new(def))))
+        }
+    } else {
+        (name, cg_type, None)
     }
 }
 
-fn get_bounds(source: &mut Peekable<impl Iterator<Item = TokenTree>>) -> HashMap<String, String> {
-    let mut ret = HashMap::new();
+fn next_generic<T: Iterator<Item = TokenTree> + Clone>(
+    source: &mut Peekable<T>,
+) -> Option<Generic> {
+    let Some(tok) = source.peek() else {
+        return None;
+    };
+    match tok {
+        TokenTree::Group(g) => {
+            if matches!(g.delimiter(), Delimiter::Brace) {
+                return None;
+            }
+            let mut bounds = vec![];
+            let _type = next_type(source).expect("must be a type in group");
+            if let Some(_) = next_exact_punct(source, ":") {
+                while let Some(bound) = next_type(source) {
+                    bounds.push(bound);
+                    if next_exact_punct(source, "+").is_none() {
+                        break;
+                    }
+                }
+            }
 
-    match source.peek() {
-        Some(content) if content.to_string() == "<" => {
+            Some(Generic::WhereBounded {
+                name: _type.full(),
+                bounds,
+            })
+        }
+        TokenTree::Ident(c) if c.to_string() == "const" => {
             source.next();
-            let mut typename = "".to_string(); 
-            let mut generic_bound = String::new();
-            let mut in_type = true;
-            while let Some(tok) = source.next() {
-                match tok.to_string().as_str() {
-                    ">" => {
-                        ret.insert(typename.clone(), generic_bound.clone());
-                        typename.clear();
-                        generic_bound.clear();
-                        break
-                    },
-                    ":" => {
-                        if in_type {
-                            in_type = false
-                        } else {
-                            generic_bound += ":";
-                        }
-                    },
-                    "," => {
-                        ret.insert(typename.clone(), generic_bound.clone());
-                        typename.clear();
-                        generic_bound.clear();
-                        in_type = true
-                    },
-                    c => {
-                        if in_type {
-                            typename+=c;
-                        } else {
-                            generic_bound += c;
+            let (name, _type, default) = next_const_generic(source);
+            Some(Generic::ConstGeneric {
+                name,
+                _type,
+                default,
+            })
+        }
+        TokenTree::Ident(_) => {
+            let mut default = None;
+            let ty = next_type(source).expect("Expected type name after \'const\' keyword");
+
+            let mut bounds = vec![];
+
+            if let Some(_) = next_exact_punct(source, ":") {
+                loop {
+                    if let Some(ty) = next_type(source) {
+                        bounds.push(ty);
+                    }
+                    if next_exact_punct(source, "+").is_none() {
+                        break;
+                    }
+                }
+            }
+
+            if let Some(_) = next_exact_punct(source, "=") {
+                default = Some(next_type(source).expect("Must be a default after eq sign"));
+            }
+            Some(Generic::Generic {
+                name: ty.full(),
+                default,
+                bounds,
+            })
+        }
+        TokenTree::Punct(punct) => match punct.as_char() {
+            '>' => None,
+            '\'' => {
+                let ty = next_lifetime(source).expect("must be lifetime after \' mark");
+                let mut bounds = vec![];
+                if let Some(_) = next_exact_punct(source, ":") {
+                    while let Some(bound) = next_lifetime(source) {
+                        bounds.push(bound);
+                        if next_exact_punct(source, "+").is_none() {
+                            break;
                         }
                     }
                 }
+                Some(Generic::Lifetime {
+                    name: ty.ident,
+                    bounds,
+                })
             }
+            _ => unimplemented!("unexpected character: {}", _debug_current_token(source)),
         },
-        _ => ()
+        TokenTree::Literal(_) => unimplemented!("should not be literals here"),
     }
-    ret
 }
 
-pub(crate) fn struct_bounds_strings(struct_: &Struct, bound_name: &str) -> (String, String) {
-    let generics: &HashMap<String, String> = &struct_.generics;
-    if generics.is_empty() {
-        return ("".to_string(), "".to_string());
+fn get_all_bounds<T: Iterator<Item = TokenTree> + Clone>(source: &mut Peekable<T>) -> Vec<Generic> {
+    let mut ret = Vec::new();
+    let mut already = HashSet::new();
+    if source.peek().map_or(false, |x| x.to_string() == "<") {
+        source.next();
+    } else {
+        return ret;
     }
-    let mut generic_w_bounds = "<".to_string();
-    for (generic, bounds) in generics.iter() {
-        let mut bounds = bounds.to_string();
-        if !bounds.is_empty() {
-            bounds += " + ";
-        }
-        bounds += &format!("nanoserde::{}", bound_name);
 
-        generic_w_bounds += &format!("{}: {}, ", generic, bounds);
+    // Angle bracket generics + bounds
+    while let Some(gen) = next_generic(source) {
+        if already.insert(gen.full()) {
+            ret.push(gen);
+        } else {
+            match (
+                ret.iter_mut().find(|x| x.full() == gen.full()).unwrap(),
+                gen,
+            ) {
+                (
+                    Generic::Generic { bounds, .. },
+                    Generic::Generic {
+                        bounds: other_bounds,
+                        ..
+                    },
+                ) => bounds.extend_from_slice(&other_bounds),
+                (
+                    Generic::Lifetime { bounds, .. },
+                    Generic::Lifetime {
+                        bounds: other_bounds,
+                        ..
+                    },
+                ) => bounds.extend_from_slice(&other_bounds),
+                (
+                    Generic::WhereBounded { bounds, .. },
+                    Generic::WhereBounded {
+                        bounds: other_bounds,
+                        ..
+                    },
+                ) => bounds.extend_from_slice(&other_bounds),
+                _ => {
+                    panic!("mismatched generic types")
+                }
+            }
+        }
+        let Some(_) = next_exact_punct(source, ",") else {
+            break;
+        };
     }
-    generic_w_bounds += ">";
 
-    let mut generic_no_bounds = "<".to_string();
-    for (generic, _bounds) in generics.iter() {
-        generic_no_bounds += &format!("{}, ", generic);
-    }
-    generic_no_bounds += ">";
-    return (generic_w_bounds, generic_no_bounds);
-}
+    let _ = next_exact_punct(source, ">").expect("Need closing generic bracket");
 
-pub(crate) fn enum_bounds_strings(enum_: &Enum, bound_name: &str) -> (String, String) {
-    let generics: &HashMap<String, String> = &enum_.generics;
+    // "where" generics + bounds
+    if let Some(content) = source.peek() {
+        if content.to_string() != "where" {
+            return ret;
+        } else {
+            source.next();
+        }
 
-    if generics.is_empty() {
-        return ("".to_string(), "".to_string());
-    }
-    let mut generic_w_bounds = "<".to_string();
-    for (generic, bounds) in generics.iter() {
-        let mut bounds = bounds.to_string();
-        if !bounds.is_empty() {
-            bounds += " + ";
+        while let Some(gen) = next_generic(source) {
+            if already.insert(gen.full()) {
+                let gen = match gen {
+                    Generic::Generic { name, bounds, .. } => Generic::WhereBounded { name, bounds },
+                    where_bounded @ Generic::WhereBounded { .. } => where_bounded,
+                    unused => {
+                        unimplemented!(
+                            "Shouldn't have unused lifetime or const generic in where bound: {}",
+                            unused.full()
+                        )
+                    }
+                };
+                ret.push(gen);
+            } else {
+                match (
+                    ret.iter_mut().find(|x| x.full() == gen.full()).unwrap(),
+                    gen,
+                ) {
+                    (
+                        Generic::Generic { bounds, .. },
+                        Generic::Generic {
+                            bounds: other_bounds,
+                            ..
+                        },
+                    ) => bounds.extend_from_slice(&other_bounds),
+                    (
+                        Generic::Lifetime { bounds, .. },
+                        Generic::Lifetime {
+                            bounds: other_bounds,
+                            ..
+                        },
+                    ) => bounds.extend_from_slice(&other_bounds),
+                    (
+                        Generic::WhereBounded { bounds, .. },
+                        Generic::WhereBounded {
+                            bounds: other_bounds,
+                            ..
+                        },
+                    ) => bounds.extend_from_slice(&other_bounds),
+                    _ => {
+                        panic!("mismatched generic types")
+                    }
+                }
+            }
+            let Some(_) = next_exact_punct(source, ",") else {
+                break;
+            };
+            let None = next_exact_punct(source, "{") else {
+                break;
+            };
         }
-        bounds += &format!("nanoserde::{}", bound_name);
-        generic_w_bounds += &format!("{}: {}, ", generic, bounds);
     }
-    generic_w_bounds += ">";
 
-    let mut generic_no_bounds = "<".to_string();
-    for (generic, _bounds) in generics.iter() {
-        generic_no_bounds += &format!("{}, ", generic);
-    }
-    generic_no_bounds += ">";
-    return (generic_w_bounds, generic_no_bounds);
+    ret
 }
 
 pub fn parse_data(input: TokenStream) -> Data {
@@ -576,7 +1496,6 @@ pub fn parse_data(input: TokenStream) -> Data {
         "struct" => {
             let mut struct_ = next_struct(&mut source);
             struct_.attributes = attributes;
-
             res = Data::Struct(struct_);
         }
         "enum" => {
@@ -589,8 +1508,8 @@ pub fn parse_data(input: TokenStream) -> Data {
 
     assert!(
         source.next().is_none(),
-        "Unexpected data after end of the struct"
+        "Unexpected data after end of the struct: {}",
+        _debug_current_token(&mut source)
     );
-
     res
 }
diff --git a/derive/src/serde_bin.rs b/derive/src/serde_bin.rs
index 184be49..752e2a9 100644
--- a/derive/src/serde_bin.rs
+++ b/derive/src/serde_bin.rs
@@ -1,7 +1,10 @@
 use alloc::format;
 use alloc::string::String;
 
-use crate::parse::{Enum, Struct, struct_bounds_strings, enum_bounds_strings};
+use crate::{
+    parse::{Category, Enum, Struct, Type},
+    shared::{enum_bounds_strings, struct_bounds_strings},
+};
 
 use proc_macro::TokenStream;
 
@@ -60,7 +63,13 @@ pub fn derive_ser_bin_struct(struct_: &Struct) -> TokenStream {
                 {}
             }}
         }}",
-        generic_w_bounds, struct_.name, generic_no_bounds, body
+        generic_w_bounds,
+        struct_
+            .name
+            .as_ref()
+            .expect("Shouldnt have an anonymous struct here"),
+        generic_no_bounds,
+        body
     )
     .parse()
     .unwrap()
@@ -84,7 +93,13 @@ pub fn derive_ser_bin_struct_unnamed(struct_: &Struct) -> TokenStream {
                 {}
             }}
         }}",
-        generic_w_bounds, struct_.name, generic_no_bounds, body
+        generic_w_bounds,
+        struct_
+            .name
+            .as_ref()
+            .expect("Shouldnt have an anonymous struct here"),
+        generic_no_bounds,
+        body
     )
     .parse()
     .unwrap()
@@ -117,7 +132,13 @@ pub fn derive_de_bin_struct(struct_: &Struct) -> TokenStream {
                 }})
             }}
         }}",
-        generic_w_bounds, struct_.name, generic_no_bounds, body
+        generic_w_bounds,
+        struct_
+            .name
+            .as_ref()
+            .expect("Shouldnt have an anonymous struct here"),
+        generic_no_bounds,
+        body
     )
     .parse()
     .unwrap()
@@ -146,7 +167,13 @@ pub fn derive_de_bin_struct_unnamed(struct_: &Struct) -> TokenStream {
                 }})
             }}
         }}",
-        generic_w_bounds, struct_.name, generic_no_bounds, body
+        generic_w_bounds,
+        struct_
+            .name
+            .as_ref()
+            .expect("Shouldnt have an anonymous struct here"),
+        generic_no_bounds,
+        body
     )
     .parse()
     .unwrap()
@@ -158,37 +185,63 @@ pub fn derive_ser_bin_enum(enum_: &Enum) -> TokenStream {
 
     for (index, variant) in enum_.variants.iter().enumerate() {
         let lit = format!("{}u16", index);
-        let ident = &variant.name;
+        let ident = variant
+            .field_name
+            .as_ref()
+            .expect("Unnamed enum fields are illegal");
         // Unit
-        if variant.fields.len() == 0 {
-            l!(r, "Self::{} => {}.ser_bin(s),", ident, lit);
-        }
-        // Named
-        else if variant.named {
-            l!(r, "Self::{} {{", variant.name);
-            for field in &variant.fields {
-                l!(r, "{}, ", field.field_name.as_ref().unwrap())
+        match &variant.ty {
+            Type {
+                wraps: None,
+                ident: Category::None,
+                ..
+            } => {
+                // unit variant
+                l!(r, "Self::{} => {}.ser_bin(s),", ident, lit);
             }
-            l!(r, "} => {");
-            l!(r, "{}.ser_bin(s);", lit);
-            for field in &variant.fields {
-                l!(r, "{}.ser_bin(s);", field.field_name.as_ref().unwrap())
+            Type {
+                ident: Category::Tuple { contents },
+                ..
+            } => {
+                l!(r, "Self::{} (", ident);
+                for (n, _) in contents.iter().enumerate() {
+                    l!(r, "f{}, ", n)
+                }
+                l!(r, ") => {");
+                l!(r, "{}.ser_bin(s);", lit);
+                for (n, _) in contents.iter().enumerate() {
+                    l!(r, "f{}.ser_bin(s);", n)
+                }
+                l!(r, "}")
             }
-            l!(r, "}")
-        }
-        // Unnamed
-        else if variant.named == false {
-            l!(r, "Self::{} (", variant.name);
-            for (n, _) in variant.fields.iter().enumerate() {
-                l!(r, "f{}, ", n)
+            Type {
+                ident: Category::AnonymousStruct { contents },
+                ..
+            } => {
+                l!(r, "Self::{} {{", ident);
+                for (_, f) in contents.fields.iter().enumerate() {
+                    l!(
+                        r,
+                        "{}, ",
+                        f.field_name.as_ref().expect("field must be named")
+                    )
+                }
+
+                l!(r, "} => {");
+                l!(r, "{}.ser_bin(s);", lit);
+                for (_, f) in contents.fields.iter().enumerate() {
+                    l!(
+                        r,
+                        "{}.ser_bin(s);",
+                        f.field_name.as_ref().expect("field must be named")
+                    )
+                }
+                l!(r, "}")
             }
-            l!(r, ") => {");
-            l!(r, "{}.ser_bin(s);", lit);
-            for (n, _) in variant.fields.iter().enumerate() {
-                l!(r, "f{}.ser_bin(s);", n)
+            v => {
+                unimplemented!("Unexpected type in enum: {:?}", v)
             }
-            l!(r, "}")
-        }
+        };
     }
 
     format!(
@@ -199,7 +252,7 @@ pub fn derive_ser_bin_enum(enum_: &Enum) -> TokenStream {
                 }}
             }}
         }}",
-        generic_w_bounds,enum_.name,generic_no_bounds, r
+        generic_w_bounds, enum_.name, generic_no_bounds, r
     )
     .parse()
     .unwrap()
@@ -212,30 +265,58 @@ pub fn derive_de_bin_enum(enum_: &Enum) -> TokenStream {
     for (index, variant) in enum_.variants.iter().enumerate() {
         let lit = format!("{}u16", index);
 
-        // Unit
-        if variant.fields.len() == 0 {
-            l!(r, "{} => Self::{},", lit, variant.name)
-        }
-        // Named
-        else if variant.named {
-            l!(r, "{} => Self::{} {{", lit, variant.name);
-            for field in &variant.fields {
+        match &variant.ty {
+            Type {
+                wraps: None,
+                ident: Category::None,
+                ..
+            } => {
+                // unit variant
                 l!(
                     r,
-                    "{}: DeBin::de_bin(o, d)?,",
-                    field.field_name.as_ref().unwrap()
+                    "{} => Self::{},",
+                    lit,
+                    variant.field_name.as_ref().unwrap()
+                )
+            }
+            Type {
+                ident: Category::Tuple { contents },
+                ..
+            } => {
+                l!(
+                    r,
+                    "{} => Self::{} (",
+                    lit,
+                    variant.field_name.as_ref().unwrap()
                 );
+                for _ in contents {
+                    l!(r, "DeBin::de_bin(o, d)?,",);
+                }
+                l!(r, "),")
             }
-            l!(r, "},");
-        }
-        // Unnamed
-        else if variant.named == false {
-            l!(r, "{} => Self::{} (", lit, variant.name);
-            for _ in &variant.fields {
-                l!(r, "DeBin::de_bin(o, d)?,");
+            Type {
+                ident: Category::AnonymousStruct { contents },
+                ..
+            } => {
+                l!(
+                    r,
+                    "{} => Self::{} {{",
+                    lit,
+                    variant.field_name.as_ref().unwrap()
+                );
+                for f in contents.fields.iter() {
+                    l!(
+                        r,
+                        "{}: DeBin::de_bin(o, d)?,",
+                        f.field_name.as_ref().unwrap()
+                    );
+                }
+                l!(r, "},");
             }
-            l!(r, "),");
-        }
+            v => {
+                unimplemented!("Unexpected type in enum: {:?}", v)
+            }
+        };
     }
 
     format!(
diff --git a/derive/src/serde_json.rs b/derive/src/serde_json.rs
index 4cc7dfb..de71f91 100644
--- a/derive/src/serde_json.rs
+++ b/derive/src/serde_json.rs
@@ -2,8 +2,10 @@ use alloc::format;
 use alloc::string::{String, ToString};
 use alloc::{vec, vec::Vec};
 
+use crate::parse::{Category, Type};
+use crate::shared::{enum_bounds_strings, struct_bounds_strings};
 use crate::{
-    parse::{Enum, Field, Struct, struct_bounds_strings, enum_bounds_strings},
+    parse::{Enum, Field, Struct},
     shared,
 };
 
@@ -47,7 +49,7 @@ pub fn derive_ser_json_struct(struct_: &Struct) -> TokenStream {
                 format!("self.{}", struct_fieldname)
             };
 
-            if field.ty.is_option {
+            if field.ty.base() == "Option" {
                 l!(
                     s,
                     "if let Some(t) = &{} {{ if first_field_was_serialized {{ s.conl(); }};first_field_was_serialized = true;s.field(d+1, \"{}\");t.ser_json(d+1, s);}};",
@@ -75,7 +77,13 @@ pub fn derive_ser_json_struct(struct_: &Struct) -> TokenStream {
             }}
         }}
     ",
-        generic_w_bounds, struct_.name, generic_no_bounds, s
+        generic_w_bounds,
+        struct_
+            .name
+            .as_ref()
+            .expect("Cannot implement for anonymous struct"),
+        generic_no_bounds,
+        s
     )
     .parse()
     .unwrap()
@@ -97,15 +105,19 @@ pub fn derive_de_json_named(name: &str, defaults: bool, fields: &[Field]) -> Tok
         let field_attr_default_with = shared::attrs_default_with(&field.attributes);
         let default_val = if let Some(v) = field_attr_default {
             if let Some(mut val) = v {
-                if field.ty.path == "String" {
+                if field.ty.base() == "String"
+                    || field.ty.wraps.as_ref().map_or(false, |wrapped| {
+                        wrapped.iter().any(|ty| ty.base() == "String")
+                    })
+                {
                     val = format!("\"{}\".to_string()", val)
                 }
-                if field.ty.is_option {
+                if field.ty.base() == "Option" {
                     val = format!("Some({})", val);
                 }
                 Some(val)
             } else {
-                if !field.ty.is_option {
+                if field.ty.base() != "Option" {
                     Some(String::from("Default::default()"))
                 } else {
                     Some(String::from("None"))
@@ -129,7 +141,7 @@ pub fn derive_de_json_named(name: &str, defaults: bool, fields: &[Field]) -> Tok
         };
 
         if skip == false {
-            if field.ty.is_option {
+            if field.ty.base() == "Option" {
                 unwraps.push(format!(
                     "{{if let Some(t) = {} {{ {} }} else {{ {} }} }}",
                     localvar,
@@ -212,7 +224,10 @@ pub fn derive_de_json_proxy(proxy_type: &str, type_: &str) -> TokenStream {
 
 pub fn derive_de_json_struct(struct_: &Struct) -> TokenStream {
     let body = derive_de_json_named(
-        &struct_.name,
+        &struct_
+            .name
+            .as_ref()
+            .expect("Cannot implement for anonymous struct"),
         shared::attrs_default(&struct_.attributes).is_some()
             || shared::attrs_default_with(&struct_.attributes).is_some(),
         &struct_.fields[..],
@@ -225,7 +240,7 @@ pub fn derive_de_json_struct(struct_: &Struct) -> TokenStream {
             nanoserde::DeJsonErr> {{
                 core::result::Result::Ok({{ {} }})
             }}
-        }}", generic_w_bounds, struct_.name, generic_no_bounds, body)
+        }}", generic_w_bounds, struct_.name.as_ref().expect("Cannot implement for anonymous struct"), generic_no_bounds, body)
         .parse().unwrap()
 }
 
@@ -233,117 +248,133 @@ pub fn derive_ser_json_enum(enum_: &Enum) -> TokenStream {
     let mut r = String::new();
 
     for variant in enum_.variants.iter() {
+        let field_name = variant.field_name.clone().unwrap();
         let json_variant_name =
-            shared::attrs_rename(&variant.attributes).unwrap_or(variant.name.clone());
-        // Unit
-        if variant.fields.len() == 0 {
-            l!(
-                r,
-                "Self::{} => s.label(\"{}\"),",
-                variant.name,
-                json_variant_name
-            );
-        }
-        // Named
-        else if variant.named {
-            let mut items = String::new();
-            let mut field_names = vec![];
-            let last = variant.fields.len() - 1;
-            for (index, field) in variant.fields.iter().enumerate() {
-                if let Some(name) = &&field.field_name {
-                    let proxied_field =
-                        if let Some(proxy) = crate::shared::attrs_proxy(&field.attributes) {
-                            format!("{{let proxy: {} = Into::into(&{});proxy}}", proxy, name)
-                        } else {
-                            format!("{}", name)
-                        };
-
-                    if index == last {
-                        if field.ty.is_option {
-                            l!(
-                                items,
-                                "if {}.is_some(){{s.field(d+1, \"{}\");{}.ser_json(d+1, s);}}",
-                                name,
-                                name,
-                                proxied_field
-                            )
-                        } else {
-                            l!(
-                                items,
-                                "s.field(d+1, \"{}\");{}.ser_json(d+1, s);",
-                                name,
-                                proxied_field
-                            )
-                        }
-                    } else {
-                        if field.ty.is_option {
-                            l!(
-                                items,
-                                "if {}.is_some(){{s.field(d+1, \"{}\");{}.ser_json(d+1, s);s.conl();}}",
-                                name,
-                                name,
-                                proxied_field
-                            );
+            shared::attrs_rename(&variant.attributes).unwrap_or(field_name.clone());
+
+        match &variant.ty {
+            Type {
+                wraps: None,
+                ident: Category::None,
+                ..
+            } => {
+                // unit variant
+                l!(
+                    r,
+                    "Self::{} => s.label(\"{}\"),",
+                    &field_name,
+                    json_variant_name
+                );
+            }
+
+            Type {
+                ident: Category::AnonymousStruct { contents },
+                ..
+            } => {
+                let mut items = String::new();
+                let mut field_names = vec![];
+                let last = contents.fields.len() - 1;
+                for (index, field) in contents.fields.iter().enumerate() {
+                    if let Some(name) = &&field.field_name {
+                        let proxied_field =
+                            if let Some(proxy) = crate::shared::attrs_proxy(&variant.attributes) {
+                                format!("{{let proxy: {} = Into::into(&{});proxy}}", proxy, name)
+                            } else {
+                                format!("{}", name)
+                            };
+
+                        if index == last {
+                            if field.ty.base() == "Option" {
+                                l!(
+                                    items,
+                                    "if {}.is_some(){{s.field(d+1, \"{}\");{}.ser_json(d+1, s);}}",
+                                    name,
+                                    name,
+                                    proxied_field
+                                )
+                            } else {
+                                l!(
+                                    items,
+                                    "s.field(d+1, \"{}\");{}.ser_json(d+1, s);",
+                                    name,
+                                    proxied_field
+                                )
+                            }
                         } else {
-                            l!(
-                                items,
-                                "s.field(d+1, \"{}\");{}.ser_json(d+1, s);s.conl();",
-                                name,
-                                proxied_field
-                            );
+                            if field.ty.base() == "Option" {
+                                l!(
+                                        items,
+                                        "if {}.is_some(){{s.field(d+1, \"{}\");{}.ser_json(d+1, s);s.conl();}}",
+                                        name,
+                                        name,
+                                        proxied_field
+                                    );
+                            } else {
+                                l!(
+                                    items,
+                                    "s.field(d+1, \"{}\");{}.ser_json(d+1, s);s.conl();",
+                                    name,
+                                    proxied_field
+                                );
+                            }
                         }
+                        field_names.push(name.clone());
                     }
-                    field_names.push(name.clone());
                 }
+                l!(
+                    r,
+                    "Self::{} {{ {} }} => {{
+                                s.out.push('{{');
+                                s.label(\"{}\");
+                                s.out.push(':');
+                                s.st_pre();
+                                {}
+                                s.st_post(d);
+                                s.out.push('}}');
+                            }}",
+                    &field_name,
+                    field_names.join(","),
+                    json_variant_name,
+                    items
+                );
             }
-            l!(
-                r,
-                "Self::{} {{ {} }} => {{
-                        s.out.push('{{');
-                        s.label(\"{}\");
-                        s.out.push(':');
-                        s.st_pre();
-                        {}
-                        s.st_post(d);
-                        s.out.push('}}');
-                    }}",
-                variant.name,
-                field_names.join(","),
-                json_variant_name,
-                items
-            );
-        }
-        // Unnamed
-        else {
-            let mut names = Vec::new();
-            let mut inner = String::new();
-            let last = variant.fields.len() - 1;
-            for (index, _) in &mut variant.fields.iter().enumerate() {
-                let field_name = format!("f{}", index);
-                names.push(field_name.clone());
-                if index != last {
-                    l!(inner, "{}.ser_json(d, s); s.out.push(',');", field_name);
-                } else {
-                    l!(inner, "{}.ser_json(d, s);", field_name);
+            Type {
+                ident: Category::Tuple { contents },
+                ..
+            } => {
+                let mut names = Vec::new();
+                let mut inner = String::new();
+                let last = contents.len() - 1;
+                for (index, _) in contents.iter().enumerate() {
+                    let field_name = format!("f{}", index);
+                    names.push(field_name.clone());
+                    if index != last {
+                        l!(inner, "{}.ser_json(d, s); s.out.push(',');", field_name);
+                    } else {
+                        l!(inner, "{}.ser_json(d, s);", field_name);
+                    }
                 }
+                l!(
+                    r,
+                    "Self::{}  ({}) => {{
+                                s.out.push('{{');
+                                s.label(\"{}\");
+                                s.out.push(':');
+                                s.out.push('[');
+                                {}
+                                s.out.push(']');
+                                s.out.push('}}');
+                            }}",
+                    &field_name,
+                    names.join(","),
+                    json_variant_name,
+                    inner
+                );
             }
-            l!(
-                r,
-                "Self::{}  ({}) => {{
-                        s.out.push('{{');
-                        s.label(\"{}\");
-                        s.out.push(':');
-                        s.out.push('[');
-                        {}
-                        s.out.push(']');
-                        s.out.push('}}');
-                    }}",
-                variant.name,
-                names.join(","),
-                json_variant_name,
-                inner
-            );
-        }
+            v => {
+                unimplemented!("Unexpected type in enum: {:?}", v)
+            }
+        };
     }
 
     format!(
@@ -367,42 +398,58 @@ pub fn derive_de_json_enum(enum_: &Enum) -> TokenStream {
     let (generic_w_bounds, generic_no_bounds) = enum_bounds_strings(enum_, "DeJson");
 
     for variant in &enum_.variants {
+        let field_name = variant.field_name.clone().unwrap();
         let json_variant_name =
-            shared::attrs_rename(&variant.attributes).unwrap_or(variant.name.clone());
-
-        // Unit
-        if variant.fields.len() == 0 {
-            l!(
-                r_units,
-                "\"{}\" => Self::{},",
-                json_variant_name,
-                variant.name
-            );
-        }
-        // Named
-        else if variant.named {
-            let body =
-                derive_de_json_named(&format!("Self::{}", variant.name), false, &variant.fields);
-            l!(r_rest, "\"{}\" => {{ {} }}, ", json_variant_name, body);
-        }
-        // Unnamed
-        else if variant.named == false {
-            let mut field_names = String::new();
-
-            for _ in &variant.fields {
+            shared::attrs_rename(&variant.attributes).unwrap_or(field_name.clone());
+
+        match &variant.ty {
+            Type {
+                wraps: None,
+                ident: Category::None,
+                ..
+            } => {
+                // unit variant
                 l!(
-                    field_names,
-                    "{let r = DeJson::de_json(s,i)?;s.eat_comma_block(i)?;r},"
+                    r_units,
+                    "\"{}\" => Self::{},",
+                    json_variant_name,
+                    &field_name
                 );
             }
-            l!(
-                r_rest,
-                "\"{}\" => {{s.block_open(i)?;let r = Self::{}({}); s.block_close(i)?;r}}",
-                json_variant_name,
-                variant.name,
-                field_names
-            );
-        }
+            Type {
+                ident: Category::AnonymousStruct { contents },
+                ..
+            } => {
+                let body = derive_de_json_named(
+                    &format!("Self::{}", &field_name),
+                    false,
+                    &contents.fields,
+                );
+                l!(r_rest, "\"{}\" => {{ {} }}, ", json_variant_name, body);
+            }
+            Type {
+                ident: Category::Tuple { contents },
+                ..
+            } => {
+                let mut field_names = String::new();
+                for _ in contents.iter() {
+                    l!(
+                        field_names,
+                        "{let r = DeJson::de_json(s,i)?;s.eat_comma_block(i)?;r},"
+                    );
+                }
+                l!(
+                    r_rest,
+                    "\"{}\" => {{s.block_open(i)?;let r = Self::{}({}); s.block_close(i)?;r}}",
+                    json_variant_name,
+                    &field_name,
+                    field_names
+                );
+            }
+            v => {
+                unimplemented!("Unexpected type in enum: {:?}", v)
+            }
+        };
     }
 
     let mut r = format!(
@@ -492,7 +539,13 @@ pub fn derive_ser_json_struct_unnamed(struct_: &Struct) -> TokenStream {
                 {}
             }}
         }}",
-        generic_w_bounds, struct_.name, generic_no_bounds, body
+        generic_w_bounds,
+        struct_
+            .name
+            .as_ref()
+            .expect("Cannot implement for anonymous struct"),
+        generic_no_bounds,
+        body
     )
     .parse()
     .unwrap()
@@ -538,6 +591,6 @@ pub fn derive_de_json_struct_unnamed(struct_: &Struct) -> TokenStream {
                 {}
                 core::result::Result::Ok(r)
             }}
-        }}",generic_w_bounds, struct_.name, generic_no_bounds, body
+        }}",generic_w_bounds, struct_.name.as_ref().expect("Cannot implement for anonymous struct"), generic_no_bounds, body
     ).parse().unwrap()
 }
diff --git a/derive/src/serde_ron.rs b/derive/src/serde_ron.rs
index e4673c9..4fb5139 100644
--- a/derive/src/serde_ron.rs
+++ b/derive/src/serde_ron.rs
@@ -2,7 +2,7 @@ use alloc::format;
 use alloc::string::{String, ToString};
 use alloc::{vec, vec::Vec};
 
-use crate::parse::{Attribute, Enum, Field, Struct};
+use crate::parse::{Attribute, Category, Enum, Field, Struct, Type};
 
 use proc_macro::TokenStream;
 
@@ -43,7 +43,7 @@ pub fn derive_ser_ron_struct(struct_: &Struct) -> TokenStream {
         let struct_fieldname = field.field_name.clone().unwrap();
         let ron_fieldname =
             shared::attrs_rename(&field.attributes).unwrap_or_else(|| struct_fieldname.clone());
-        if field.ty.is_option {
+        if field.ty.base() == "Option" {
             l!(
                 s,
                 "if let Some(t) = &self.{} {{
@@ -76,7 +76,11 @@ pub fn derive_ser_ron_struct(struct_: &Struct) -> TokenStream {
             }}
         }}
     ",
-        struct_.name, s
+        struct_
+            .name
+            .as_ref()
+            .expect("Cannot implement for anonymous struct"),
+        s
     )
     .parse()
     .unwrap()
@@ -101,7 +105,11 @@ pub fn derive_ser_ron_struct_unnamed(struct_: &Struct) -> TokenStream {
                 s.out.push(')');
             }}
         }}",
-        struct_.name, body
+        struct_
+            .name
+            .as_ref()
+            .expect("Cannot implement for anonymous struct"),
+        body
     )
     .parse()
     .unwrap()
@@ -126,15 +134,15 @@ pub fn derive_de_ron_named(
         let field_attr_default_with = shared::attrs_default_with(&field.attributes);
         let default_val = if let Some(v) = field_attr_default {
             if let Some(mut val) = v {
-                if field.ty.path == "String" {
+                if field.ty.base() == "String" {
                     val = format!("\"{}\".to_string()", val)
                 }
-                if field.ty.is_option {
+                if field.ty.base() == "Option" {
                     val = format!("Some({})", val);
                 }
                 Some(val)
             } else {
-                if !field.ty.is_option {
+                if field.ty.base() != "Option" {
                     Some(String::from("Default::default()"))
                 } else {
                     Some(String::from("None"))
@@ -149,7 +157,7 @@ pub fn derive_de_ron_named(
         let ron_fieldname =
             shared::attrs_rename(&field.attributes).unwrap_or(struct_fieldname.clone());
 
-        if field.ty.is_option {
+        if field.ty.base() == "Option" {
             unwraps.push(format!(
                 "{{
                     if let Some(t) = {} {{
@@ -245,14 +253,21 @@ pub fn derive_de_ron_named(
 }
 
 pub fn derive_de_ron_struct(struct_: &Struct) -> TokenStream {
-    let body = derive_de_ron_named(&struct_.name, &struct_.fields, &struct_.attributes);
+    let body = derive_de_ron_named(
+        &struct_
+            .name
+            .as_ref()
+            .expect("Cannot implement for anonymous struct"),
+        &struct_.fields,
+        &struct_.attributes,
+    );
 
     format!(
         "impl DeRon for {} {{
             fn de_ron(s: &mut nanoserde::DeRonState, i: &mut core::str::Chars) -> core::result::Result<Self,nanoserde::DeRonErr> {{
                 core::result::Result::Ok({})
             }}
-        }}", struct_.name, body)
+        }}", struct_.name.as_ref().expect("Cannot implement for anonymous struct"), body)
     .parse()
     .unwrap()
 }
@@ -279,7 +294,7 @@ pub fn derive_de_ron_struct_unnamed(struct_: &Struct) -> TokenStream {
                 s.paren_close(i)?;
                 core::result::Result::Ok(r)
             }}
-        }}",struct_.name, body
+        }}",struct_.name.as_ref().expect("Cannot implement for anonymous struct"), body
     ).parse().unwrap()
 }
 
@@ -287,19 +302,25 @@ pub fn derive_ser_ron_enum(enum_: &Enum) -> TokenStream {
     let mut body = String::new();
 
     for variant in &enum_.variants {
-        let ident = &variant.name;
-        // Unit
-        if variant.fields.len() == 0 {
-            l!(body, "Self::{} => s.out.push_str(\"{}\"),", ident, ident)
-        }
-        // Named
-        else if variant.named {
-            let mut names = Vec::new();
-            let mut inner = String::new();
-            for field in &variant.fields {
-                if let Some(name) = &field.field_name {
+        let ident = &variant.field_name.clone().unwrap();
+        match &variant.ty {
+            Type {
+                ident: Category::None,
+                ..
+            } => {
+                // unit variant
+                l!(body, "Self::{} => s.out.push_str(\"{}\"),", ident, ident)
+            }
+            Type {
+                ident: Category::AnonymousStruct { contents },
+                ..
+            } => {
+                let mut names = Vec::new();
+                let mut inner = String::new();
+                for (_, field) in contents.fields.iter().enumerate() {
+                    let name = field.field_name.as_ref().unwrap();
                     names.push(name.clone());
-                    if field.ty.is_option {
+                    if field.ty.base() == "Option" {
                         l!(
                             inner,
                             "if {}.is_some() {{
@@ -307,9 +328,9 @@ pub fn derive_ser_ron_enum(enum_: &Enum) -> TokenStream {
                                 {}.ser_ron(d+1, s);
                                 s.conl();
                             }}",
-                            name,
-                            name,
-                            name
+                            name.as_str(),
+                            name.as_str(),
+                            name.as_str()
                         )
                     } else {
                         l!(
@@ -322,48 +343,53 @@ pub fn derive_ser_ron_enum(enum_: &Enum) -> TokenStream {
                         )
                     }
                 }
+                l!(
+                    body,
+                    "Self::{} {{ {} }} => {{
+                        s.out.push_str(\"{}\");
+                        s.st_pre();
+                        {}
+                        s.st_post(d);
+                    }}",
+                    ident,
+                    names.join(","),
+                    ident,
+                    inner
+                );
             }
-            l!(
-                body,
-                "Self::{} {{ {} }} => {{
-                    s.out.push_str(\"{}\");
-                    s.st_pre();
-                    {}
-                    s.st_post(d);
-                }}",
-                ident,
-                names.join(","),
-                ident,
-                inner
-            )
-        }
-        // Unnamed
-        else {
-            let mut names = Vec::new();
-            let mut inner = String::new();
-            let last = variant.fields.len() - 1;
-            for (index, _) in &mut variant.fields.iter().enumerate() {
-                let name = format!("f{}", index);
-                l!(inner, "{}.ser_ron(d, s);", name);
-                if index != last {
-                    l!(inner, "s.out.push_str(\", \");")
+            Type {
+                ident: Category::Tuple { contents },
+                ..
+            } => {
+                let mut names = Vec::new();
+                let mut inner = String::new();
+                let last = contents.len() - 1;
+                for (index, _) in &mut contents.iter().enumerate() {
+                    let name = format!("f{}", index);
+                    l!(inner, "{}.ser_ron(d, s);", name);
+                    if index != last {
+                        l!(inner, "s.out.push_str(\", \");")
+                    }
+                    names.push(name);
                 }
-                names.push(name);
+                l!(
+                    body,
+                    "Self::{} ({}) => {{
+                        s.out.push_str(\"{}\");
+                        s.out.push('(');
+                        {}
+                        s.out.push(')');
+                    }}",
+                    ident,
+                    names.join(","),
+                    ident,
+                    inner
+                )
             }
-            l!(
-                body,
-                "Self::{} ({}) => {{
-                    s.out.push_str(\"{}\");
-                    s.out.push('(');
-                    {}
-                    s.out.push(')');
-                }}",
-                ident,
-                names.join(","),
-                ident,
-                inner
-            )
-        }
+            v => {
+                unimplemented!("Unexpected type in enum: {:?}", v)
+            }
+        };
     }
     format!(
         "
@@ -382,45 +408,59 @@ pub fn derive_ser_ron_enum(enum_: &Enum) -> TokenStream {
 
 pub fn derive_de_ron_enum(enum_: &Enum) -> TokenStream {
     let mut body = String::new();
-
     for variant in &enum_.variants {
-        let ident = &variant.name;
-        // Unit
-        if variant.fields.len() == 0 {
-            l!(body, "\"{}\" => Self::{},", ident, ident)
-        }
-        // Named
-        else if variant.named {
-            let name = format!("{}::{}", enum_.name, variant.name);
-            let inner = derive_de_ron_named(&name, &variant.fields, &vec![]);
-            l!(body, "\"{}\" => {}", ident, inner);
-        }
-        // Unnamed
-        else {
-            let mut inner = String::new();
-            for _ in &variant.fields {
+        let ident = variant.field_name.clone().unwrap();
+
+        match &variant.ty {
+            Type {
+                wraps: None,
+                ident: Category::None,
+                ..
+            } => {
+                // unit variant
+                l!(body, "\"{}\" => Self::{},", ident, ident)
+            }
+            Type {
+                ident: Category::AnonymousStruct { contents },
+                ..
+            } => {
+                let name = format!("{}::{}", enum_.name, ident);
+                let inner = derive_de_ron_named(&name, &contents.fields, &vec![]);
+                l!(body, "\"{}\" => {}", ident, inner);
+            }
+            Type {
+                ident: Category::Tuple { contents },
+                ..
+            } => {
+                let mut inner = String::new();
+                for _ in contents.iter() {
+                    l!(
+                        inner,
+                        "{
+                            let r = DeRon::de_ron(s, i)?;
+                            s.eat_comma_paren(i)?;
+                            r
+                        }, "
+                    )
+                }
+
                 l!(
-                    inner,
-                    "{
-                        let r = DeRon::de_ron(s, i)?;
-                        s.eat_comma_paren(i)?;
+                    body,
+                    "\"{}\" => {{
+                        s.paren_open(i)?;
+                        let r = Self::{} ({});
+                        s.paren_close(i)?;
                         r
-                    }, "
-                )
+                    }}, ",
+                    ident,
+                    ident,
+                    inner
+                );
             }
-            l!(
-                body,
-                "\"{}\" => {{
-                    s.paren_open(i)?;
-                    let r = Self::{} ({});
-                    s.paren_close(i)?;
-                    r
-                }}, ",
-                ident,
-                ident,
-                inner
-            );
-        }
+            v => {
+                unimplemented!("Unexpected type in enum: {:?}", v)
+            }
+        };
     }
 
     format! ("
diff --git a/derive/src/shared.rs b/derive/src/shared.rs
index 835a14e..f5ddb2c 100644
--- a/derive/src/shared.rs
+++ b/derive/src/shared.rs
@@ -1,5 +1,7 @@
 use alloc::string::String;
 
+use crate::parse::{Enum, Struct};
+
 macro_rules! l {
     ($target:ident, $line:expr) => {
         $target.push_str($line)
@@ -63,3 +65,51 @@ pub fn attrs_skip(attributes: &[crate::parse::Attribute]) -> bool {
         .iter()
         .any(|attr| attr.tokens.len() == 1 && attr.tokens[0] == "skip")
 }
+
+pub(crate) fn struct_bounds_strings(struct_: &Struct, bound_name: &str) -> (String, String) {
+    let generics: &Vec<_> = &struct_.generics;
+
+    if generics.is_empty() {
+        return ("".to_string(), "".to_string());
+    }
+    let mut generic_w_bounds = "<".to_string();
+    for generic in generics.iter() {
+        generic_w_bounds += generic
+            .full_with_const(&[format!("nanoserde::{}", bound_name).as_str()], true)
+            .as_str();
+        generic_w_bounds += ", ";
+    }
+    generic_w_bounds += ">";
+
+    let mut generic_no_bounds = "<".to_string();
+    for generic in generics.iter() {
+        generic_no_bounds += generic.ident_only().as_str();
+        generic_no_bounds += ", ";
+    }
+    generic_no_bounds += ">";
+    return (generic_w_bounds, generic_no_bounds);
+}
+
+pub(crate) fn enum_bounds_strings(enum_: &Enum, bound_name: &str) -> (String, String) {
+    let generics: &Vec<_> = &enum_.generics;
+
+    if generics.is_empty() {
+        return ("".to_string(), "".to_string());
+    }
+    let mut generic_w_bounds = "<".to_string();
+    for generic in generics.iter() {
+        generic_w_bounds += generic
+            .full_with_const(&[format!("nanoserde::{}", bound_name).as_str()], true)
+            .as_str();
+        generic_w_bounds += ", ";
+    }
+    generic_w_bounds += ">";
+
+    let mut generic_no_bounds = "<".to_string();
+    for generic in generics.iter() {
+        generic_no_bounds += generic.ident_only().as_str();
+        generic_no_bounds += ", ";
+    }
+    generic_no_bounds += ">";
+    return (generic_w_bounds, generic_no_bounds);
+}
diff --git a/src/serde_bin.rs b/src/serde_bin.rs
index d8e75fc..0f2c8d9 100644
--- a/src/serde_bin.rs
+++ b/src/serde_bin.rs
@@ -497,7 +497,7 @@ where
 
 impl<K, V> DeBin for HashMap<K, V>
 where
-    K: DeBin + Eq + Hash,
+    K: DeBin + std::cmp::Eq + std::hash::Hash,
     V: DeBin,
 {
     fn de_bin(o: &mut usize, d: &[u8]) -> Result<Self, DeBinErr> {


Test patch:
diff --git a/tests/bin.rs b/tests/bin.rs
index dfdcccd..af83d4a 100644
--- a/tests/bin.rs
+++ b/tests/bin.rs
@@ -1,4 +1,4 @@
-use std::collections::{BTreeSet, HashSet, LinkedList};
+use std::collections::{BTreeSet, HashMap, HashSet, LinkedList};
 
 use nanoserde::{DeBin, SerBin};
 
@@ -29,12 +29,25 @@ fn binary() {
 #[test]
 fn binary_generics() {
     #[derive(DeBin, SerBin, PartialEq)]
-    pub struct TestStruct<A, B> {
-        pub a: A,
-        b: Option<B>,
-    }
-
-    let test: TestStruct<i32, f32> = TestStruct { a: 1, b: Some(2.) };
+    struct TestGenericsWSkip<A, B, C, DD: Eq + std::hash::Hash, EE>
+    where
+        EE: Eq + std::hash::Hash,
+    {
+        test1: A,
+        test2: B,
+        test3: C,
+        #[nserde(skip)]
+        test4: HashMap<DD, A>,
+        test5: HashMap<EE, A>,
+    }
+
+    let test: TestGenericsWSkip<i32, usize, String, Option<bool>, u128> = TestGenericsWSkip {
+        test1: 0,
+        test2: 42,
+        test3: String::from("test123"),
+        test4: vec![(Some(true), 1)].into_iter().collect(),
+        test5: vec![(15_u128, 1)].into_iter().collect(),
+    };
 
     let bytes = SerBin::serialize_bin(&test);
 
@@ -44,10 +57,11 @@ fn binary_generics() {
 
     #[derive(DeBin, SerBin, PartialEq)]
     pub enum TestEnum<A, B> {
-        Test(A, B),
+        Test1(A, B),
+        Test2(B, A),
     }
 
-    let test: TestEnum<i32, f32> = TestEnum::Test(3, 15.);
+    let test: TestEnum<i32, f32> = TestEnum::Test1(3, 15.);
 
     let bytes = SerBin::serialize_bin(&test);