#[cfg(feature = "color")]
pub mod color;
pub mod custom;
pub mod style;
use proc_macro2::TokenStream;
use quote::quote;
use crate::core::Field;
pub struct DisplayOptions<'a> {
pub name: String,
pub fields: &'a [&'a Field],
pub is_named: bool,
pub use_self: bool,
}
pub enum SegmentKind {
Name,
FieldName,
Value,
OpenDelim,
CloseDelim,
Separator,
Assign,
}
pub struct Segment {
#[allow(dead_code)]
pub kind: SegmentKind,
pub text: Option<String>,
pub arg: Option<TokenStream>,
}
impl Segment {
pub fn literal(kind: SegmentKind, text: &str) -> Self {
Self {
kind,
text: Some(text.to_string()),
arg: None,
}
}
pub fn placeholder(kind: SegmentKind, arg: TokenStream) -> Self {
Self {
kind,
text: None,
arg: Some(arg),
}
}
}
pub struct DisplayOutput {
pub segments: Vec<Segment>,
}
impl DisplayOutput {
pub fn new() -> Self {
Self {
segments: Vec::new(),
}
}
pub fn push(&mut self, seg: Segment) {
self.segments.push(seg);
}
}
impl quote::ToTokens for DisplayOutput {
fn to_tokens(&self, tokens: &mut TokenStream) {
let mut fmt = String::new();
let mut args: Vec<TokenStream> = Vec::new();
for seg in &self.segments {
match (&seg.text, &seg.arg) {
(Some(text), None) => {
fmt.push_str(&text.replace('{', "{{").replace('}', "}}"));
}
(None, Some(arg)) => {
fmt.push_str("{}");
args.push(arg.clone());
}
_ => {}
}
}
let output = if args.is_empty() {
quote! { ::std::write!(f, #fmt) }
} else {
quote! { ::std::write!(f, #fmt, #(#args),*) }
};
tokens.extend(output);
}
}