Repository: zhiburt/tabled (rust)

Issue:
Hidden fields shouldn't need to implement Display
I have a field of a struct which I do not plan to show in the table output. However, despite adding:
```rust
    #[header(hidden = true)]
    foo: SomeType
```
I still have an error compiling the struct, saying `SomeType` doesn't implement display. Obviously, I don't want to go through the trouble of implementing `Display` for a type I don't plan to list in the table. If possible, there should be a way to completely disable parsing for this field so that not having `Display` implemented for a field which is hidden doesn't error out.

Pull request description:
tabled_derive/ fix requirment for fmt::Display on hidden fields in in…
closes #32 

Patch:
diff --git a/Cargo.toml b/Cargo.toml
index d1b7268..4780029 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,7 +24,7 @@ maintenance = { status = "actively-developed" }
 color = ["papergrid/color", "ansi-cut"]
 
 [dependencies]
-tabled_derive = "0.1.8"
+tabled_derive = { path = "./tabled_derive" }
 papergrid = { path = "./papergrid" }
 ansi-cut = { version = "0.1.1", optional = true }
 
diff --git a/tabled_derive/src/lib.rs b/tabled_derive/src/lib.rs
index d11f47b..edbb6d3 100644
--- a/tabled_derive/src/lib.rs
+++ b/tabled_derive/src/lib.rs
@@ -124,6 +124,10 @@ fn variant_headers(variant: &Variant, attr: &Attr) -> Vec<proc_macro2::TokenStre
         let mut calls = Vec::new();
         for (index, field) in variant.fields.iter().enumerate() {
             let field_attr = Attr::parse(&field.attrs);
+            if field_attr.is_ignored() {
+                continue;
+            }
+
             let call = field_headers(field, &field_attr, index, prefix);
             calls.push(call);
         }
@@ -303,6 +307,7 @@ fn variant_fields(v: &Variant, attr: &Attr) -> Vec<proc_macro2::TokenStream> {
     branch_idents
         .into_iter()
         .zip(v.fields.iter().map(|field| Attr::parse(&field.attrs)))
+        .filter(|(_, attr)| !attr.is_ignored())
         .map(|(ident, attr)| get_field_fields(ident.to_token_stream(), &attr))
         .collect()
 }
@@ -311,6 +316,8 @@ fn variant_idents(v: &Variant) -> Vec<Ident> {
     v.fields
         .iter()
         .enumerate()
+        // we intentionally not ignore these fields to be able to build a pattern correctly
+        // .filter(|(_, field)| !Attr::parse(&field.attrs).is_ignored())
         .map(|(index, field)| {
             if let Some(ident) = field.ident.as_ref() {
                 ident.clone()


Test patch:
diff --git a/tests/derive_test.rs b/tests/derive_test.rs
index b6033cb..37d4926 100644
--- a/tests/derive_test.rs
+++ b/tests/derive_test.rs
@@ -589,3 +589,159 @@ mod structure {
         assert_eq!(vec!["f1".to_owned(), "f2".to_owned()], St::headers());
     }
 }
+
+#[test]
+fn hidden_fields_may_not_implement_display() {
+    {
+        struct Something;
+
+        #[derive(Tabled)]
+        struct TupleStruct(#[header(hidden = true)] Something, &'static str);
+
+        let st = TupleStruct(Something, "nrdxp");
+
+        assert_eq!(vec!["nrdxp".to_owned()], st.fields());
+        assert_eq!(vec!["1".to_owned()], TupleStruct::headers());
+    }
+
+    {
+        struct Something;
+
+        #[derive(Tabled)]
+        struct Struct {
+            #[header(hidden = true)]
+            _gem: Something,
+            name: &'static str,
+        }
+
+        let st = Struct {
+            _gem: Something,
+            name: "nrdxp",
+        };
+
+        assert_eq!(vec!["nrdxp".to_owned()], st.fields());
+        assert_eq!(vec!["name".to_owned()], Struct::headers());
+    }
+
+    {
+        struct Something;
+
+        #[derive(Tabled)]
+        struct Struct1 {
+            #[header(hidden = true)]
+            _field1: Something,
+            field2: &'static str,
+        }
+
+        #[derive(Tabled)]
+        struct Struct2 {
+            field1: &'static str,
+            #[field(inline)]
+            field2: Struct1,
+        }
+
+        let st = Struct2 {
+            field1: "nrdxp",
+            field2: Struct1 {
+                _field1: Something,
+                field2: "...",
+            },
+        };
+
+        assert_eq!(
+            vec!["field1".to_owned(), "field2".to_owned()],
+            Struct2::headers()
+        );
+        assert_eq!(vec!["nrdxp".to_owned(), "...".to_owned()], st.fields());
+    }
+
+    {
+        struct Something;
+
+        #[derive(Tabled)]
+        enum Enum {
+            #[field(inline("A::"))]
+            A {
+                name: &'static str,
+            },
+            #[field(inline("B::"))]
+            B {
+                issue: usize,
+                #[header(hidden = true)]
+                _gem: Something,
+                name: &'static str,
+            },
+            #[field(inline("C::"))]
+            C(usize, #[header(hidden = true)] Something, &'static str),
+            D,
+        }
+
+        assert_eq!(
+            vec![
+                "A::name".to_owned(),
+                "B::issue".to_owned(),
+                "B::name".to_owned(),
+                "C::0".to_owned(),
+                "C::2".to_owned(),
+                "D".to_owned()
+            ],
+            Enum::headers()
+        );
+
+        let st = Enum::A { name: "nrdxp" };
+        assert_eq!(
+            vec![
+                "nrdxp".to_owned(),
+                "".to_owned(),
+                "".to_owned(),
+                "".to_owned(),
+                "".to_owned(),
+                "".to_owned()
+            ],
+            st.fields()
+        );
+
+        let st = Enum::B {
+            _gem: Something,
+            issue: 32,
+            name: "nrdxp",
+        };
+        assert_eq!(
+            vec![
+                "".to_owned(),
+                "32".to_owned(),
+                "nrdxp".to_owned(),
+                "".to_owned(),
+                "".to_owned(),
+                "".to_owned()
+            ],
+            st.fields()
+        );
+
+        let st = Enum::C(32, Something, "nrdxp");
+        assert_eq!(
+            vec![
+                "".to_owned(),
+                "".to_owned(),
+                "".to_owned(),
+                "32".to_owned(),
+                "nrdxp".to_owned(),
+                "".to_owned()
+            ],
+            st.fields()
+        );
+
+        let st = Enum::D;
+        assert_eq!(
+            vec![
+                "".to_owned(),
+                "".to_owned(),
+                "".to_owned(),
+                "".to_owned(),
+                "".to_owned(),
+                "+".to_owned()
+            ],
+            st.fields()
+        );
+    }
+}