rust/syn/meta.rs

Source file repositories/reference/linux-study-clean/rust/syn/meta.rs

File Facts

System
Linux kernel
Corpus path
rust/syn/meta.rs
Extension
.rs
Size
14184 bytes
Lines
430
Domain
Rust Kernel Layer
Bucket
Rust API Membrane
Inferred role
Rust Kernel Layer: implementation source
Status
source implementation candidate

Why This File Exists

Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: Apache-2.0 OR MIT

//! Facility for interpreting structured content inside of an `Attribute`.

use crate::error::{Error, Result};
use crate::ext::IdentExt as _;
use crate::lit::Lit;
use crate::parse::{ParseStream, Parser};
use crate::path::{Path, PathSegment};
use crate::punctuated::Punctuated;
use proc_macro2::Ident;
use std::fmt::Display;

/// Make a parser that is usable with `parse_macro_input!` in a
/// `#[proc_macro_attribute]` macro.
///
/// *Warning:* When parsing attribute args **other than** the
/// `proc_macro::TokenStream` input of a `proc_macro_attribute`, you do **not**
/// need this function. In several cases your callers will get worse error
/// messages if you use this function, because the surrounding delimiter's span
/// is concealed from attribute macros by rustc. Use
/// [`Attribute::parse_nested_meta`] instead.
///
/// [`Attribute::parse_nested_meta`]: crate::Attribute::parse_nested_meta
///
/// # Example
///
/// This example implements an attribute macro whose invocations look like this:
///
/// ```
/// # const IGNORE: &str = stringify! {
/// #[tea(kind = "EarlGrey", hot)]
/// struct Picard {...}
/// # };
/// ```
///
/// The "parameters" supported by the attribute are:
///
/// - `kind = "..."`
/// - `hot`
/// - `with(sugar, milk, ...)`, a comma-separated list of ingredients
///
/// ```
/// # extern crate proc_macro;
/// #
/// use proc_macro::TokenStream;
/// use syn::{parse_macro_input, LitStr, Path};
///
/// # const IGNORE: &str = stringify! {
/// #[proc_macro_attribute]
/// # };
/// pub fn tea(args: TokenStream, input: TokenStream) -> TokenStream {
///     let mut kind: Option<LitStr> = None;
///     let mut hot: bool = false;
///     let mut with: Vec<Path> = Vec::new();
///     let tea_parser = syn::meta::parser(|meta| {
///         if meta.path.is_ident("kind") {
///             kind = Some(meta.value()?.parse()?);
///             Ok(())
///         } else if meta.path.is_ident("hot") {
///             hot = true;
///             Ok(())
///         } else if meta.path.is_ident("with") {
///             meta.parse_nested_meta(|meta| {
///                 with.push(meta.path);
///                 Ok(())
///             })
///         } else {
///             Err(meta.error("unsupported tea property"))
///         }
///     });
///
///     parse_macro_input!(args with tea_parser);
///     eprintln!("kind={kind:?} hot={hot} with={with:?}");
///
///     /* ... */
/// #   TokenStream::new()
/// }
/// ```
///
/// The `syn::meta` library will take care of dealing with the commas including
/// trailing commas, and producing sensible error messages on unexpected input.
///
/// ```console
/// error: expected `,`
///  --> src/main.rs:3:37
///   |
/// 3 | #[tea(kind = "EarlGrey", with(sugar = "lol", milk))]
///   |                                     ^
/// ```

Annotation

Implementation Notes