summaryrefslogtreecommitdiffstats
path: root/vendor/tracing-attributes/src/attr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/tracing-attributes/src/attr.rs')
-rw-r--r--vendor/tracing-attributes/src/attr.rs190
1 files changed, 117 insertions, 73 deletions
diff --git a/vendor/tracing-attributes/src/attr.rs b/vendor/tracing-attributes/src/attr.rs
index ff875e179..f5ad40939 100644
--- a/vendor/tracing-attributes/src/attr.rs
+++ b/vendor/tracing-attributes/src/attr.rs
@@ -6,6 +6,14 @@ use quote::{quote, quote_spanned, ToTokens};
use syn::ext::IdentExt as _;
use syn::parse::{Parse, ParseStream};
+/// Arguments to `#[instrument(err(...))]` and `#[instrument(ret(...))]` which describe how the
+/// return value event should be emitted.
+#[derive(Clone, Default, Debug)]
+pub(crate) struct EventArgs {
+ level: Option<Level>,
+ pub(crate) mode: FormatMode,
+}
+
#[derive(Clone, Default, Debug)]
pub(crate) struct InstrumentArgs {
level: Option<Level>,
@@ -16,51 +24,15 @@ pub(crate) struct InstrumentArgs {
pub(crate) skips: HashSet<Ident>,
pub(crate) skip_all: bool,
pub(crate) fields: Option<Fields>,
- pub(crate) err_mode: Option<FormatMode>,
- pub(crate) ret_mode: Option<FormatMode>,
+ pub(crate) err_args: Option<EventArgs>,
+ pub(crate) ret_args: Option<EventArgs>,
/// Errors describing any unrecognized parse inputs that we skipped.
parse_warnings: Vec<syn::Error>,
}
impl InstrumentArgs {
- pub(crate) fn level(&self) -> impl ToTokens {
- fn is_level(lit: &LitInt, expected: u64) -> bool {
- match lit.base10_parse::<u64>() {
- Ok(value) => value == expected,
- Err(_) => false,
- }
- }
-
- match &self.level {
- Some(Level::Str(ref lit)) if lit.value().eq_ignore_ascii_case("trace") => {
- quote!(tracing::Level::TRACE)
- }
- Some(Level::Str(ref lit)) if lit.value().eq_ignore_ascii_case("debug") => {
- quote!(tracing::Level::DEBUG)
- }
- Some(Level::Str(ref lit)) if lit.value().eq_ignore_ascii_case("info") => {
- quote!(tracing::Level::INFO)
- }
- Some(Level::Str(ref lit)) if lit.value().eq_ignore_ascii_case("warn") => {
- quote!(tracing::Level::WARN)
- }
- Some(Level::Str(ref lit)) if lit.value().eq_ignore_ascii_case("error") => {
- quote!(tracing::Level::ERROR)
- }
- Some(Level::Int(ref lit)) if is_level(lit, 1) => quote!(tracing::Level::TRACE),
- Some(Level::Int(ref lit)) if is_level(lit, 2) => quote!(tracing::Level::DEBUG),
- Some(Level::Int(ref lit)) if is_level(lit, 3) => quote!(tracing::Level::INFO),
- Some(Level::Int(ref lit)) if is_level(lit, 4) => quote!(tracing::Level::WARN),
- Some(Level::Int(ref lit)) if is_level(lit, 5) => quote!(tracing::Level::ERROR),
- Some(Level::Path(ref pat)) => quote!(#pat),
- Some(_) => quote! {
- compile_error!(
- "unknown verbosity level, expected one of \"trace\", \
- \"debug\", \"info\", \"warn\", or \"error\", or a number 1-5"
- )
- },
- None => quote!(tracing::Level::INFO),
- }
+ pub(crate) fn level(&self) -> Level {
+ self.level.clone().unwrap_or(Level::Info)
}
pub(crate) fn target(&self) -> impl ToTokens {
@@ -167,12 +139,12 @@ impl Parse for InstrumentArgs {
args.fields = Some(input.parse()?);
} else if lookahead.peek(kw::err) {
let _ = input.parse::<kw::err>();
- let mode = FormatMode::parse(input)?;
- args.err_mode = Some(mode);
+ let err_args = EventArgs::parse(input)?;
+ args.err_args = Some(err_args);
} else if lookahead.peek(kw::ret) {
let _ = input.parse::<kw::ret>()?;
- let mode = FormatMode::parse(input)?;
- args.ret_mode = Some(mode);
+ let ret_args = EventArgs::parse(input)?;
+ args.ret_args = Some(ret_args);
} else if lookahead.peek(Token![,]) {
let _ = input.parse::<Token![,]>()?;
} else {
@@ -190,6 +162,55 @@ impl Parse for InstrumentArgs {
}
}
+impl EventArgs {
+ pub(crate) fn level(&self, default: Level) -> Level {
+ self.level.clone().unwrap_or(default)
+ }
+}
+
+impl Parse for EventArgs {
+ fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
+ if !input.peek(syn::token::Paren) {
+ return Ok(Self::default());
+ }
+ let content;
+ let _ = syn::parenthesized!(content in input);
+ let mut result = Self::default();
+ let mut parse_one_arg =
+ || {
+ let lookahead = content.lookahead1();
+ if lookahead.peek(kw::level) {
+ if result.level.is_some() {
+ return Err(content.error("expected only a single `level` argument"));
+ }
+ result.level = Some(content.parse()?);
+ } else if result.mode != FormatMode::default() {
+ return Err(content.error("expected only a single format argument"));
+ } else if let Some(ident) = content.parse::<Option<Ident>>()? {
+ match ident.to_string().as_str() {
+ "Debug" => result.mode = FormatMode::Debug,
+ "Display" => result.mode = FormatMode::Display,
+ _ => return Err(syn::Error::new(
+ ident.span(),
+ "unknown event formatting mode, expected either `Debug` or `Display`",
+ )),
+ }
+ }
+ Ok(())
+ };
+ parse_one_arg()?;
+ if !content.is_empty() {
+ if content.lookahead1().peek(Token![,]) {
+ let _ = content.parse::<Token![,]>()?;
+ parse_one_arg()?;
+ } else {
+ return Err(content.error("expected `,` or `)`"));
+ }
+ }
+ Ok(result)
+ }
+}
+
struct StrArg<T> {
value: LitStr,
_p: std::marker::PhantomData<T>,
@@ -231,7 +252,7 @@ impl Parse for Skips {
let _ = input.parse::<kw::skip>();
let content;
let _ = syn::parenthesized!(content in input);
- let names: Punctuated<Ident, Token![,]> = content.parse_terminated(Ident::parse_any)?;
+ let names = content.parse_terminated(Ident::parse_any, Token![,])?;
let mut skips = HashSet::new();
for name in names {
if skips.contains(&name) {
@@ -260,27 +281,6 @@ impl Default for FormatMode {
}
}
-impl Parse for FormatMode {
- fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
- if !input.peek(syn::token::Paren) {
- return Ok(FormatMode::default());
- }
- let content;
- let _ = syn::parenthesized!(content in input);
- let maybe_mode: Option<Ident> = content.parse()?;
- maybe_mode.map_or(Ok(FormatMode::default()), |ident| {
- match ident.to_string().as_str() {
- "Debug" => Ok(FormatMode::Debug),
- "Display" => Ok(FormatMode::Display),
- _ => Err(syn::Error::new(
- ident.span(),
- "unknown error mode, must be Debug or Display",
- )),
- }
- })
- }
-}
-
#[derive(Clone, Debug)]
pub(crate) struct Fields(pub(crate) Punctuated<Field, Token![,]>);
@@ -303,7 +303,7 @@ impl Parse for Fields {
let _ = input.parse::<kw::fields>();
let content;
let _ = syn::parenthesized!(content in input);
- let fields: Punctuated<_, Token![,]> = content.parse_terminated(Field::parse)?;
+ let fields = content.parse_terminated(Field::parse, Token![,])?;
Ok(Self(fields))
}
}
@@ -348,7 +348,7 @@ impl ToTokens for Field {
let name = &self.name;
let kind = &self.kind;
tokens.extend(quote! {
- #name = #kind#value
+ #name = #kind #value
})
} else if self.kind == FieldKind::Value {
// XXX(eliza): I don't like that fields without values produce
@@ -376,9 +376,12 @@ impl ToTokens for FieldKind {
}
#[derive(Clone, Debug)]
-enum Level {
- Str(LitStr),
- Int(LitInt),
+pub(crate) enum Level {
+ Trace,
+ Debug,
+ Info,
+ Warn,
+ Error,
Path(Path),
}
@@ -388,9 +391,37 @@ impl Parse for Level {
let _ = input.parse::<Token![=]>()?;
let lookahead = input.lookahead1();
if lookahead.peek(LitStr) {
- Ok(Self::Str(input.parse()?))
+ let str: LitStr = input.parse()?;
+ match str.value() {
+ s if s.eq_ignore_ascii_case("trace") => Ok(Level::Trace),
+ s if s.eq_ignore_ascii_case("debug") => Ok(Level::Debug),
+ s if s.eq_ignore_ascii_case("info") => Ok(Level::Info),
+ s if s.eq_ignore_ascii_case("warn") => Ok(Level::Warn),
+ s if s.eq_ignore_ascii_case("error") => Ok(Level::Error),
+ _ => Err(input.error(
+ "unknown verbosity level, expected one of \"trace\", \
+ \"debug\", \"info\", \"warn\", or \"error\", or a number 1-5",
+ )),
+ }
} else if lookahead.peek(LitInt) {
- Ok(Self::Int(input.parse()?))
+ fn is_level(lit: &LitInt, expected: u64) -> bool {
+ match lit.base10_parse::<u64>() {
+ Ok(value) => value == expected,
+ Err(_) => false,
+ }
+ }
+ let int: LitInt = input.parse()?;
+ match &int {
+ i if is_level(i, 1) => Ok(Level::Trace),
+ i if is_level(i, 2) => Ok(Level::Debug),
+ i if is_level(i, 3) => Ok(Level::Info),
+ i if is_level(i, 4) => Ok(Level::Warn),
+ i if is_level(i, 5) => Ok(Level::Error),
+ _ => Err(input.error(
+ "unknown verbosity level, expected one of \"trace\", \
+ \"debug\", \"info\", \"warn\", or \"error\", or a number 1-5",
+ )),
+ }
} else if lookahead.peek(Ident) {
Ok(Self::Path(input.parse()?))
} else {
@@ -399,6 +430,19 @@ impl Parse for Level {
}
}
+impl ToTokens for Level {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ Level::Trace => tokens.extend(quote!(tracing::Level::TRACE)),
+ Level::Debug => tokens.extend(quote!(tracing::Level::DEBUG)),
+ Level::Info => tokens.extend(quote!(tracing::Level::INFO)),
+ Level::Warn => tokens.extend(quote!(tracing::Level::WARN)),
+ Level::Error => tokens.extend(quote!(tracing::Level::ERROR)),
+ Level::Path(ref pat) => tokens.extend(quote!(#pat)),
+ }
+ }
+}
+
mod kw {
syn::custom_keyword!(fields);
syn::custom_keyword!(skip);