implement Display for enums with attribute config_type (#3621)

This commit is contained in:
Stéphane Campinas 2019-06-12 13:20:42 +02:00 committed by Seiichi Uchida
parent 71fa7946a1
commit 04add0cd38
4 changed files with 75 additions and 2 deletions

View File

@ -23,6 +23,7 @@ pub fn define_config_type_on_enum(em: &syn::ItemEnum) -> syn::Result<TokenStream
let impl_doc_hint = impl_doc_hint(&em.ident, &em.variants);
let impl_from_str = impl_from_str(&em.ident, &em.variants);
let impl_display = impl_display(&em.ident, &em.variants);
let impl_serde = impl_serde(&em.ident, &em.variants);
let impl_deserialize = impl_deserialize(&em.ident, &em.variants);
@ -31,6 +32,7 @@ pub fn define_config_type_on_enum(em: &syn::ItemEnum) -> syn::Result<TokenStream
mod #mod_name {
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub #enum_token #ident #generics { #variants }
#impl_display
#impl_doc_hint
#impl_from_str
#impl_serde
@ -68,6 +70,29 @@ fn impl_doc_hint(ident: &syn::Ident, variants: &Variants) -> TokenStream {
}
}
fn impl_display(ident: &syn::Ident, variants: &Variants) -> TokenStream {
let vs = variants
.iter()
.filter(|v| is_unit(v))
.map(|v| (config_value_of_variant(v), &v.ident));
let match_patterns = fold_quote(vs, |(s, v)| {
quote! {
#ident::#v => write!(f, "{}", #s),
}
});
quote! {
use std::fmt;
impl fmt::Display for #ident {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
#match_patterns
_ => unimplemented!(),
}
}
}
}
}
fn impl_from_str(ident: &syn::Ident, variants: &Variants) -> TokenStream {
let vs = variants
.iter()

View File

@ -249,11 +249,15 @@ macro_rules! create_config {
}
name_out.push_str(name_raw);
name_out.push(' ');
let mut default_str = format!("{}", $def);
if default_str.is_empty() {
default_str = String::from("\"\"");
}
writeln!(out,
"{}{} Default: {:?}{}",
"{}{} Default: {}{}",
name_out,
<$ty>::doc_hint(),
$def,
default_str,
if !$stb { " (unstable)" } else { "" }).unwrap();
$(
writeln!(out, "{}{}", space_str, $dstring).unwrap();

View File

@ -1,5 +1,6 @@
//! This module contains types and functions to support formatting specific line ranges.
use itertools::Itertools;
use std::collections::HashMap;
use std::path::PathBuf;
use std::rc::Rc;
@ -92,6 +93,12 @@ impl<'a> From<&'a LineRange> for Range {
}
}
impl fmt::Display for Range {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}..{}", self.lo, self.hi)
}
}
impl Range {
pub fn new(lo: usize, hi: usize) -> Range {
Range { lo, hi }
@ -149,6 +156,21 @@ impl Range {
#[derive(Clone, Debug, Default, PartialEq)]
pub struct FileLines(Option<HashMap<FileName, Vec<Range>>>);
impl fmt::Display for FileLines {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
None => write!(f, "None")?,
Some(map) => {
for (file_name, ranges) in map.iter() {
write!(f, "{}: ", file_name)?;
write!(f, "{}\n", ranges.iter().format(", "))?;
}
}
};
Ok(())
}
}
/// Normalizes the ranges so that the invariants for `FileLines` hold: ranges are non-overlapping,
/// and ordered by their start point.
fn normalize_ranges(ranges: &mut HashMap<FileName, Vec<Range>>) {

View File

@ -3,6 +3,7 @@ use std::fmt;
use std::path::{Path, PathBuf};
use atty;
use itertools::Itertools;
use rustfmt_config_proc_macro::config_type;
use serde::de::{SeqAccess, Visitor};
use serde::ser::SerializeSeq;
@ -193,6 +194,12 @@ pub struct WidthHeuristics {
pub single_line_if_else_max_width: usize,
}
impl fmt::Display for WidthHeuristics {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl WidthHeuristics {
// Using this WidthHeuristics means we ignore heuristics.
pub fn null() -> WidthHeuristics {
@ -264,6 +271,21 @@ pub struct IgnoreList {
rustfmt_toml_path: PathBuf,
}
impl fmt::Display for IgnoreList {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"[{}]",
self.path_set
.iter()
.format_with(", ", |path, f| f(&format_args!(
"{}",
path.to_string_lossy()
)))
)
}
}
impl Serialize for IgnoreList {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where