File Index
Files and directories
Sign in
FILE

lifetime.rs

File preview with syntax highlighting.

linux-6.19.14/rust/syn/lifetime.rs RUST
  1// SPDX-License-Identifier: Apache-2.0 OR MIT
  2
  3#[cfg(feature = "parsing")]
  4use crate::lookahead;
  5use proc_macro2::{Ident, Span};
  6use std::cmp::Ordering;
  7use std::fmt::{self, Display};
  8use std::hash::{Hash, Hasher};
  9
 10/// A Rust lifetime: `'a`.
 11///
 12/// Lifetime names must conform to the following rules:
 13///
 14/// - Must start with an apostrophe.
 15/// - Must not consist of just an apostrophe: `'`.
 16/// - Character after the apostrophe must be `_` or a Unicode code point with
 17///   the XID_Start property.
 18/// - All following characters must be Unicode code points with the XID_Continue
 19///   property.
 20pub struct Lifetime {
 21    pub apostrophe: Span,
 22    pub ident: Ident,
 23}
 24
 25impl Lifetime {
 26    /// # Panics
 27    ///
 28    /// Panics if the lifetime does not conform to the bulleted rules above.
 29    ///
 30    /// # Invocation
 31    ///
 32    /// ```
 33    /// # use proc_macro2::Span;
 34    /// # use syn::Lifetime;
 35    /// #
 36    /// # fn f() -> Lifetime {
 37    /// Lifetime::new("'a", Span::call_site())
 38    /// # }
 39    /// ```
 40    pub fn new(symbol: &str, span: Span) -> Self {
 41        if !symbol.starts_with('\'') {
 42            panic!(
 43                "lifetime name must start with apostrophe as in \"'a\", got {:?}",
 44                symbol
 45            );
 46        }
 47
 48        if symbol == "'" {
 49            panic!("lifetime name must not be empty");
 50        }
 51
 52        if !crate::ident::xid_ok(&symbol[1..]) {
 53            panic!("{:?} is not a valid lifetime name", symbol);
 54        }
 55
 56        Lifetime {
 57            apostrophe: span,
 58            ident: Ident::new(&symbol[1..], span),
 59        }
 60    }
 61
 62    pub fn span(&self) -> Span {
 63        self.apostrophe
 64            .join(self.ident.span())
 65            .unwrap_or(self.apostrophe)
 66    }
 67
 68    pub fn set_span(&mut self, span: Span) {
 69        self.apostrophe = span;
 70        self.ident.set_span(span);
 71    }
 72}
 73
 74impl Display for Lifetime {
 75    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
 76        "'".fmt(formatter)?;
 77        self.ident.fmt(formatter)
 78    }
 79}
 80
 81impl Clone for Lifetime {
 82    fn clone(&self) -> Self {
 83        Lifetime {
 84            apostrophe: self.apostrophe,
 85            ident: self.ident.clone(),
 86        }
 87    }
 88}
 89
 90impl PartialEq for Lifetime {
 91    fn eq(&self, other: &Lifetime) -> bool {
 92        self.ident.eq(&other.ident)
 93    }
 94}
 95
 96impl Eq for Lifetime {}
 97
 98impl PartialOrd for Lifetime {
 99    fn partial_cmp(&self, other: &Lifetime) -> Option<Ordering> {
100        Some(self.cmp(other))
101    }
102}
103
104impl Ord for Lifetime {
105    fn cmp(&self, other: &Lifetime) -> Ordering {
106        self.ident.cmp(&other.ident)
107    }
108}
109
110impl Hash for Lifetime {
111    fn hash<H: Hasher>(&self, h: &mut H) {
112        self.ident.hash(h);
113    }
114}
115
116#[cfg(feature = "parsing")]
117pub_if_not_doc! {
118    #[doc(hidden)]
119    #[allow(non_snake_case)]
120    pub fn Lifetime(marker: lookahead::TokenMarker) -> Lifetime {
121        match marker {}
122    }
123}
124
125#[cfg(feature = "parsing")]
126pub(crate) mod parsing {
127    use crate::error::Result;
128    use crate::lifetime::Lifetime;
129    use crate::parse::{Parse, ParseStream};
130
131    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
132    impl Parse for Lifetime {
133        fn parse(input: ParseStream) -> Result<Self> {
134            input.step(|cursor| {
135                cursor
136                    .lifetime()
137                    .ok_or_else(|| cursor.error("expected lifetime"))
138            })
139        }
140    }
141}
142
143#[cfg(feature = "printing")]
144mod printing {
145    use crate::lifetime::Lifetime;
146    use proc_macro2::{Punct, Spacing, TokenStream};
147    use quote::{ToTokens, TokenStreamExt};
148
149    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
150    impl ToTokens for Lifetime {
151        fn to_tokens(&self, tokens: &mut TokenStream) {
152            let mut apostrophe = Punct::new('\'', Spacing::Joint);
153            apostrophe.set_span(self.apostrophe);
154            tokens.append(apostrophe);
155            self.ident.to_tokens(tokens);
156        }
157    }
158}
~/ Read-only file preview.