Repository: zhiburt/tabled (language: rust)

Issue:
"the trait `From<std::path::Display<'_>>` is not implemented for `Cow<'_, _>`"
The following example results in an error spelled out in the title:

```rust
#[derive(tabled::Tabled)]
struct MyStruct<'a> {
    #[tabled(display_with("std::path::Path::display"))]
    path: &'a std::path::Path,
}
```

`tabled` only says that it requires types to be `Display`, but here is it also trying to construct a `Cow` of something from that `Display` impl.


Discussion / hints:
Hi @elenakrittik 
Thanks for bringing it up.


> tabled only says that it requires types to be Display

True

If what you're saying is true; then it must be considered a bug.
(I very much believe it's the case)

Don't you wanna fix it yourself? (Just asking in case you're interested to)
It shall be a small fix down here, and a few tests.

https://github.com/zhiburt/tabled/blob/fa06ecfb180649fef55141cae8dfd8db11a8a2c5/tabled_derive/src/lib.rs#L448
https://github.com/zhiburt/tabled/blob/fa06ecfb180649fef55141cae8dfd8db11a8a2c5/tabled_derive/src/lib.rs#L392

Interesting....

Thanks once again.
Let me know if you'll have time.
> Don't you wanna fix it yourself? (Just asking in case you're interested to) It shall be a small fix down here, and a few tests.

I would be glad to help, but i'm not sure i understand the "real" issue here. I tried playing around with the lines you've mentioned (removing `Cow`, forcing `Cow::Borrowed` or `Cow::Owned`) but in every case the change broke tests and/or examples. I also noticed that `Cow` is mandatory because the `Tabled` trait itself mandates return types to be `Vec<Cow<...>>`. If "fixing" this will get too much into the core of `tabled`, maybe this should just be documented instead?

Fix patch:
diff --git a/json_to_table/src/table/collapsed_table.rs b/json_to_table/src/table/collapsed_table.rs
index e84a40d3..bbc88710 100644
--- a/json_to_table/src/table/collapsed_table.rs
+++ b/json_to_table/src/table/collapsed_table.rs
@@ -108,7 +108,7 @@ fn _collapsed_table(val: &Value, cfg: &Config, dims: &Dimensions, ctx: PrintCont
 }
 
 fn generate_vertical_array(
-    list: &Vec<Value>,
+    list: &[Value],
     cfg: &Config,
     dims: &Dimensions,
     ctx: PrintContext,
@@ -178,7 +178,7 @@ fn generate_vertical_array(
 }
 
 fn generate_horizontal_array(
-    list: &Vec<Value>,
+    list: &[Value],
     cfg: &Config,
     dims: &Dimensions,
     ctx: PrintContext,
diff --git a/papergrid/src/records/vec_records/mod.rs b/papergrid/src/records/vec_records/mod.rs
index 1b49b98e..15d3bb4b 100644
--- a/papergrid/src/records/vec_records/mod.rs
+++ b/papergrid/src/records/vec_records/mod.rs
@@ -26,7 +26,7 @@ impl<T> VecRecords<T> {
     ///
     /// It assumes that data vector has all rows has the same length().
     pub fn new(data: Vec<Vec<T>>) -> Self {
-        let count_columns = data.get(0).map_or(0, |row| row.len());
+        let count_columns = data.first().map_or(0, |row| row.len());
         let count_rows = data.len();
         let shape = (count_rows, count_columns);
 
diff --git a/tabled/Cargo.toml b/tabled/Cargo.toml
index c52a4e4d..d39a0eea 100644
--- a/tabled/Cargo.toml
+++ b/tabled/Cargo.toml
@@ -298,7 +298,7 @@ macros = ["std"]
 
 [dependencies]
 papergrid = { version = "0.11", default-features = false }
-tabled_derive = { version = "0.7", optional = true }
+tabled_derive = { path = "../tabled_derive", optional = true }
 ansi-str = { version = "0.8", optional = true }
 ansitok = { version = "0.2", optional = true }
 unicode-width = "0.1"
diff --git a/tabled/src/grid/records/resizable.rs b/tabled/src/grid/records/resizable.rs
index a53b0587..860d6111 100644
--- a/tabled/src/grid/records/resizable.rs
+++ b/tabled/src/grid/records/resizable.rs
@@ -94,7 +94,7 @@ where
     }
 
     fn push_row(&mut self) {
-        let count_columns = self.get(0).map(|l| l.len()).unwrap_or(0);
+        let count_columns = self.first().map(|l| l.len()).unwrap_or(0);
         self.push(vec![T::default(); count_columns]);
     }
 
@@ -115,7 +115,7 @@ where
     }
 
     fn insert_row(&mut self, row: usize) {
-        let count_columns = self.get(0).map(|l| l.len()).unwrap_or(0);
+        let count_columns = self.first().map(|l| l.len()).unwrap_or(0);
         self.insert(row, vec![T::default(); count_columns]);
     }
 
@@ -157,7 +157,7 @@ where
         let records = std::mem::replace(self, VecRecords::new(vec![]));
         let mut data: Vec<Vec<_>> = records.into();
 
-        let count_columns = data.get(0).map(|l| l.len()).unwrap_or(0);
+        let count_columns = data.first().map(|l| l.len()).unwrap_or(0);
         data.push(vec![T::default(); count_columns]);
 
         *self = VecRecords::new(data);
@@ -198,7 +198,7 @@ where
         let records = std::mem::replace(self, VecRecords::new(vec![]));
         let mut data: Vec<Vec<_>> = records.into();
 
-        let count_columns = data.get(0).map(|l| l.len()).unwrap_or(0);
+        let count_columns = data.first().map(|l| l.len()).unwrap_or(0);
         data.insert(row, vec![T::default(); count_columns]);
 
         *self = VecRecords::new(data);
diff --git a/tabled/src/tables/table_pool.rs b/tabled/src/tables/table_pool.rs
index 8a7a93a0..2891e0c8 100644
--- a/tabled/src/tables/table_pool.rs
+++ b/tabled/src/tables/table_pool.rs
@@ -355,7 +355,7 @@ mod print {
     }
 
     fn generate_table_column(
-        list: &Vec<TableValue>,
+        list: &[TableValue],
         cfg: &CompactMultilineConfig,
         dims: &Dimensions,
         priority: PoolTableDimension,
@@ -444,7 +444,7 @@ mod print {
     }
 
     fn generate_table_row(
-        list: &Vec<TableValue>,
+        list: &[TableValue],
         cfg: &CompactMultilineConfig,
         dims: &Dimensions,
         priority: PoolTableDimension,
diff --git a/tabled_derive/src/lib.rs b/tabled_derive/src/lib.rs
index ccfb65b0..26a1f355 100644
--- a/tabled_derive/src/lib.rs
+++ b/tabled_derive/src/lib.rs
@@ -384,12 +384,12 @@ fn info_from_variant(
             },
         };
 
-        let call = match args {
+        let result = match args {
             Some(args) => use_function(&args, func),
             None => use_function_no_args(func),
         };
 
-        quote! { ::std::borrow::Cow::from(#call) }
+        quote! { ::std::borrow::Cow::from(format!("{}", #result)) }
     } else {
         let default_value = "+";
         quote! { ::std::borrow::Cow::Borrowed(#default_value) }
@@ -440,12 +440,12 @@ fn get_field_fields(field: &TokenStream, attr: &Attributes) -> TokenStream {
             },
         };
 
-        let call = match args {
+        let result = match args {
             Some(args) => use_function(&args, func),
             None => use_function_no_args(func),
         };
 
-        return quote!(vec![::std::borrow::Cow::from(#call)]);
+        return quote!(vec![::std::borrow::Cow::from(format!("{}", #result))]);
     }
 
     quote!(vec![::std::borrow::Cow::Owned(format!("{}", #field))])


Test patch:
diff --git a/table_to_html/tests/html.rs b/table_to_html/tests/html.rs
index af4e49da..15749f90 100644
--- a/table_to_html/tests/html.rs
+++ b/table_to_html/tests/html.rs
@@ -70,7 +70,7 @@ fn html_element_visitor() {
 
 #[test]
 fn html_element_visitor_mut() {
-    struct Visitor(usize);
+    struct Visitor;
 
     impl HtmlVisitorMut for Visitor {
         fn visit_element_mut(&mut self, e: &mut HtmlElement) -> bool {
@@ -108,7 +108,7 @@ fn html_element_visitor_mut() {
         )])),
     );
 
-    let mut visitor = Visitor(0);
+    let mut visitor = Visitor;
     table.visit_mut(&mut visitor);
 
     assert_table!(
diff --git a/tabled/tests/derive/derive_test.rs b/tabled/tests/derive/derive_test.rs
index d27e43ee..e742583f 100644
--- a/tabled/tests/derive/derive_test.rs
+++ b/tabled/tests/derive/derive_test.rs
@@ -1081,6 +1081,15 @@ fn test_skip_enum_0() {
     assert_eq!(Letters::Digit.fields(), vec!["", ""]);
 }
 
+#[test]
+fn test_display_with_2() {
+    #[derive(tabled::Tabled)]
+    struct Struct<'a> {
+        #[tabled(display_with("std::path::Path::display"))]
+        path: &'a std::path::Path,
+    }
+}
+
 mod __ {
     #[test]
     fn dont_import_the_trait() {