#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AttributeTarget {
Struct,
StructField,
Enum,
Function,
}
pub struct AttributeInfo {
pub name: &'static str,
pub detail: &'static str,
targets: &'static [AttributeTarget],
}
impl AttributeInfo {
pub fn applies_to(&self, target: AttributeTarget) -> bool {
self.targets.contains(&target)
}
}
use AttributeTarget::*;
pub const SERIALIZATION_KEYS: &[&str] = &[
"json",
"xml",
"yaml",
"toml",
"db",
"bson",
"mapstructure",
"msgpack",
];
pub const ATTRIBUTES: &[AttributeInfo] = &[
AttributeInfo {
name: "json",
detail: "JSON serialization tag",
targets: &[Struct, StructField, Enum],
},
AttributeInfo {
name: "xml",
detail: "XML serialization tag",
targets: &[Struct, StructField],
},
AttributeInfo {
name: "yaml",
detail: "YAML serialization tag",
targets: &[Struct, StructField],
},
AttributeInfo {
name: "toml",
detail: "TOML serialization tag",
targets: &[Struct, StructField],
},
AttributeInfo {
name: "db",
detail: "database column tag",
targets: &[Struct, StructField],
},
AttributeInfo {
name: "bson",
detail: "BSON serialization tag",
targets: &[Struct, StructField],
},
AttributeInfo {
name: "mapstructure",
detail: "mapstructure decoding tag",
targets: &[Struct, StructField],
},
AttributeInfo {
name: "msgpack",
detail: "MessagePack serialization tag",
targets: &[Struct, StructField],
},
AttributeInfo {
name: "tag",
detail: "Go struct tag (struct-level defaults or per-field)",
targets: &[Struct, StructField],
},
AttributeInfo {
name: "allow",
detail: "suppress a lint",
targets: &[Function],
},
AttributeInfo {
name: "iterate",
detail: "synthesize `variants` for an enum",
targets: &[Enum],
},
AttributeInfo {
name: "display",
detail: "derive `to_string`",
targets: &[Struct, Enum],
},
];
pub fn is_known_attribute(name: &str) -> bool {
name == "go" || ATTRIBUTES.iter().any(|a| a.name == name)
}
pub fn is_serialization_key(key: &str) -> bool {
SERIALIZATION_KEYS.contains(&key)
}
pub fn known_attribute_names() -> Vec<&'static str> {
ATTRIBUTES.iter().map(|a| a.name).collect()
}
pub fn attributes_for(target: AttributeTarget) -> impl Iterator<Item = &'static AttributeInfo> {
ATTRIBUTES.iter().filter(move |a| a.applies_to(target))
}