Skip to content

Commit

Permalink
Rework display_type
Browse files Browse the repository at this point in the history
  • Loading branch information
zhiburt committed Jan 31, 2025
1 parent d91f120 commit 175a8cd
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 28 deletions.
2 changes: 1 addition & 1 deletion tabled/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ macros = ["std"]

[dependencies]
papergrid = { path = "../papergrid", default-features = false }
tabled_derive = { version = "0.9", optional = true }
tabled_derive = { path = "../tabled_derive", optional = true }
ansi-str = { version = "0.9", optional = true }
ansitok = { version = "0.3", optional = true }

Expand Down
2 changes: 1 addition & 1 deletion tabled/examples/derive/display_with_option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn display_option(opt: &Option<String>) -> String {
}

#[derive(Tabled)]
#[tabled(display_option_with = "display_option")]
#[tabled(display_type(Option<String>, "display_option"))]
pub struct CountryDisplay {
name: String,
capital: Option<String>,
Expand Down
2 changes: 1 addition & 1 deletion tabled_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ license = "MIT"
proc-macro = true

[dependencies]
syn = { version = "2", features = ["full", "visit-mut"] }
syn = { version = "2", features = ["full", "visit-mut", "extra-traits"] }
quote = "1"
proc-macro2 = "1"
heck = "0.5"
Expand Down
10 changes: 5 additions & 5 deletions tabled_derive/src/attributes/type_attr.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use syn::Attribute;
use syn::{Attribute, TypePath};

use crate::{
casing_style::CasingStyle,
error::Error,
parse::type_attr::{parse_type_attributes, TypeAttr, TypeAttrKind},
};

#[derive(Debug, Default)]
#[derive(Default)]
pub struct TypeAttributes {
pub rename_all: Option<CasingStyle>,
pub inline: bool,
pub inline_value: Option<String>,
pub crate_name: Option<String>,
pub display_option_with: Option<String>,
pub display_types: Vec<(TypePath, String)>,
}

impl TypeAttributes {
Expand Down Expand Up @@ -54,8 +54,8 @@ impl TypeAttributes {
TypeAttrKind::RenameAll(lit) => {
self.rename_all = Some(CasingStyle::from_lit(&lit)?);
}
TypeAttrKind::DisplayOptionWith(func) => {
self.display_option_with = Some(func.value());
TypeAttrKind::DisplayType(type_name, func) => {
self.display_types.push((type_name, func.value()));
}
}

Expand Down
26 changes: 15 additions & 11 deletions tabled_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::{collections::HashMap, str};
use syn::visit_mut::VisitMut;
use syn::{
parse_macro_input, token, Data, DataEnum, DataStruct, DeriveInput, ExprPath, Field, Fields,
Ident, Index, PathSegment, Type, Variant,
Ident, Index, PathSegment, Type, TypePath, Variant,
};

use crate::attributes::{FieldAttributes, TypeAttributes};
Expand Down Expand Up @@ -551,23 +551,27 @@ fn get_field_fields(
return quote!(vec![::std::borrow::Cow::Owned(#call)]);
}

if is_option_type(field_type) {
if let Some(func) = &type_attrs.display_option_with {
let func = use_function(&quote!(&#field), func);
return quote!(vec![::std::borrow::Cow::from(format!("{}", #func))]);
}
if let Some(func) = find_display_type(field_type, &type_attrs.display_types) {
let func = use_function(&quote!(&#field), &func);
return quote!(vec![::std::borrow::Cow::from(format!("{}", #func))]);
}

quote!(vec![::std::borrow::Cow::Owned(format!("{}", #field))])
}

fn is_option_type(ty: &Type) -> bool {
if let Type::Path(type_path) = ty {
if let Some(segment) = type_path.path.segments.last() {
return segment.ident == "Option";
fn find_display_type(ty: &Type, types: &[(TypePath, String)]) -> Option<String> {
let path: &TypePath = match ty {
Type::Path(path) => path,
_ => return None,
};

for (display_type, display_func) in types {
if display_type.path == path.path {
return Some(display_func.clone());
}
}
false

None
}

fn use_function(args: &TokenStream, function: &str) -> TokenStream {
Expand Down
24 changes: 15 additions & 9 deletions tabled_derive/src/parse/type_attr.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use proc_macro2::{Ident, Span};
use syn::{
parenthesized, parse::Parse, punctuated::Punctuated, spanned::Spanned, token, Attribute,
LitBool, LitStr, Token,
LitBool, LitStr, Token, TypePath,
};

pub fn parse_type_attributes(
Expand Down Expand Up @@ -29,7 +29,7 @@ pub enum TypeAttrKind {
Inline(LitBool, Option<LitStr>),
RenameAll(LitStr),
Crate(LitStr),
DisplayOptionWith(LitStr),
DisplayType(TypePath, LitStr),
}

impl Parse for TypeAttr {
Expand All @@ -53,17 +53,15 @@ impl Parse for TypeAttr {
if input.peek(LitStr) {
let lit = input.parse::<LitStr>()?;

match name_str.as_str() {
"rename_all" => return Ok(Self::new(RenameAll(lit))),
"display_option_with" => return Ok(Self::new(DisplayOptionWith(lit))),
_ => {}
if name_str.as_str() == "rename_all" {
return Ok(Self::new(RenameAll(lit)));
}
}

if input.peek(LitBool) {
let lit = input.parse::<LitBool>()?;

if let "inline" = name_str.as_str() {
if name_str.as_str() == "inline" {
return Ok(Self::new(Inline(lit, None)));
}
}
Expand All @@ -81,21 +79,29 @@ impl Parse for TypeAttr {
if nested.peek(LitStr) {
let lit = nested.parse::<LitStr>()?;

if let "inline" = name_str.as_str() {
if name_str.as_str() == "inline" {
return Ok(Self::new(Inline(
LitBool::new(true, Span::call_site()),
Some(lit),
)));
}
}

if name_str.as_str() == "display_type" {
let path = nested.parse::<TypePath>()?;
let _comma = nested.parse::<Token![,]>()?;
let lit = nested.parse::<LitStr>()?;

return Ok(Self::new(DisplayType(path, lit)));
}

return Err(syn::Error::new(
_paren.span.span(),
"expected a `string literal` in parenthesis",
));
}

if let "inline" = name_str.as_str() {
if name_str.as_str() == "inline" {
return Ok(Self::new(Inline(
LitBool::new(true, Span::call_site()),
None,
Expand Down

0 comments on commit 175a8cd

Please sign in to comment.