1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
use std::default::Default; use syn::{Ident, LitStr, Variant}; use super::case_style::{CaseStyle, CaseStyleHelpers}; use super::metadata::{kw, VariantExt, VariantMeta}; use super::occurrence_error; pub trait HasStrumVariantProperties { fn get_variant_properties(&self) -> syn::Result<StrumVariantProperties>; } #[derive(Clone, Eq, PartialEq, Debug, Default)] pub struct StrumVariantProperties { pub disabled: Option<kw::disabled>, pub default: Option<kw::default>, pub message: Option<LitStr>, pub detailed_message: Option<LitStr>, pub string_props: Vec<(LitStr, LitStr)>, serialize: Vec<LitStr>, to_string: Option<LitStr>, ident: Option<Ident>, } impl StrumVariantProperties { fn ident_as_str(&self, case_style: Option<CaseStyle>) -> LitStr { let ident = self.ident.as_ref().expect("identifier"); LitStr::new(&ident.convert_case(case_style), ident.span()) } pub fn get_preferred_name(&self, case_style: Option<CaseStyle>) -> LitStr { if let Some(to_string) = &self.to_string { to_string.clone() } else { let mut serialized = self.serialize.clone(); serialized.sort_by_key(|s| s.value().len()); if let Some(n) = serialized.pop() { n } else { self.ident_as_str(case_style) } } } pub fn get_serializations(&self, case_style: Option<CaseStyle>) -> Vec<LitStr> { let mut attrs = self.serialize.clone(); if let Some(to_string) = &self.to_string { attrs.push(to_string.clone()); } if attrs.is_empty() { attrs.push(self.ident_as_str(case_style)); } attrs } } impl HasStrumVariantProperties for Variant { fn get_variant_properties(&self) -> syn::Result<StrumVariantProperties> { let mut output = StrumVariantProperties::default(); output.ident = Some(self.ident.clone()); let mut message_kw = None; let mut detailed_message_kw = None; let mut to_string_kw = None; let mut disabled_kw = None; let mut default_kw = None; for meta in self.get_metadata()? { match meta { VariantMeta::Message { value, kw } => { if let Some(fst_kw) = message_kw { return Err(occurrence_error(fst_kw, kw, "message")); } message_kw = Some(kw); output.message = Some(value); } VariantMeta::DetailedMessage { value, kw } => { if let Some(fst_kw) = detailed_message_kw { return Err(occurrence_error(fst_kw, kw, "detailed_message")); } detailed_message_kw = Some(kw); output.detailed_message = Some(value); } VariantMeta::Serialize { value, .. } => { output.serialize.push(value); } VariantMeta::ToString { value, kw } => { if let Some(fst_kw) = to_string_kw { return Err(occurrence_error(fst_kw, kw, "to_string")); } to_string_kw = Some(kw); output.to_string = Some(value); } VariantMeta::Disabled(kw) => { if let Some(fst_kw) = disabled_kw { return Err(occurrence_error(fst_kw, kw, "disabled")); } disabled_kw = Some(kw); output.disabled = Some(kw); } VariantMeta::Default(kw) => { if let Some(fst_kw) = default_kw { return Err(occurrence_error(fst_kw, kw, "default")); } default_kw = Some(kw); output.default = Some(kw); } VariantMeta::Props { props, .. } => { output.string_props.extend(props); } } } Ok(output) } }