From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- third_party/rust/time-macros/src/error.rs | 123 ++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 third_party/rust/time-macros/src/error.rs (limited to 'third_party/rust/time-macros/src/error.rs') diff --git a/third_party/rust/time-macros/src/error.rs b/third_party/rust/time-macros/src/error.rs new file mode 100644 index 0000000000..849317f15f --- /dev/null +++ b/third_party/rust/time-macros/src/error.rs @@ -0,0 +1,123 @@ +use std::borrow::Cow; +use std::fmt; + +use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; + +trait WithSpan { + fn with_span(self, span: Span) -> Self; +} + +impl WithSpan for TokenTree { + fn with_span(mut self, span: Span) -> Self { + self.set_span(span); + self + } +} + +pub(crate) enum Error { + MissingComponent { + name: &'static str, + span_start: Option, + span_end: Option, + }, + InvalidComponent { + name: &'static str, + value: String, + span_start: Option, + span_end: Option, + }, + #[cfg(any(feature = "formatting", feature = "parsing"))] + ExpectedString { + span_start: Option, + span_end: Option, + }, + UnexpectedToken { + tree: TokenTree, + }, + UnexpectedEndOfInput, + Custom { + message: Cow<'static, str>, + span_start: Option, + span_end: Option, + }, +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::MissingComponent { name, .. } => write!(f, "missing component: {name}"), + Self::InvalidComponent { name, value, .. } => { + write!(f, "invalid component: {name} was {value}") + } + #[cfg(any(feature = "formatting", feature = "parsing"))] + Self::ExpectedString { .. } => f.write_str("expected string literal"), + Self::UnexpectedToken { tree } => write!(f, "unexpected token: {tree}"), + Self::UnexpectedEndOfInput => f.write_str("unexpected end of input"), + Self::Custom { message, .. } => f.write_str(message), + } + } +} + +impl Error { + fn span_start(&self) -> Span { + match self { + Self::MissingComponent { span_start, .. } + | Self::InvalidComponent { span_start, .. } + | Self::Custom { span_start, .. } => *span_start, + #[cfg(any(feature = "formatting", feature = "parsing"))] + Self::ExpectedString { span_start, .. } => *span_start, + Self::UnexpectedToken { tree } => Some(tree.span()), + Self::UnexpectedEndOfInput => Some(Span::mixed_site()), + } + .unwrap_or_else(Span::mixed_site) + } + + fn span_end(&self) -> Span { + match self { + Self::MissingComponent { span_end, .. } + | Self::InvalidComponent { span_end, .. } + | Self::Custom { span_end, .. } => *span_end, + #[cfg(any(feature = "formatting", feature = "parsing"))] + Self::ExpectedString { span_end, .. } => *span_end, + Self::UnexpectedToken { tree, .. } => Some(tree.span()), + Self::UnexpectedEndOfInput => Some(Span::mixed_site()), + } + .unwrap_or_else(|| self.span_start()) + } + + pub(crate) fn to_compile_error(&self) -> TokenStream { + let (start, end) = (self.span_start(), self.span_end()); + + [ + TokenTree::from(Punct::new(':', Spacing::Joint)).with_span(start), + TokenTree::from(Punct::new(':', Spacing::Alone)).with_span(start), + TokenTree::from(Ident::new("core", start)), + TokenTree::from(Punct::new(':', Spacing::Joint)).with_span(start), + TokenTree::from(Punct::new(':', Spacing::Alone)).with_span(start), + TokenTree::from(Ident::new("compile_error", start)), + TokenTree::from(Punct::new('!', Spacing::Alone)).with_span(start), + TokenTree::from(Group::new( + Delimiter::Parenthesis, + TokenStream::from( + TokenTree::from(Literal::string(&self.to_string())).with_span(end), + ), + )) + .with_span(end), + ] + .iter() + .cloned() + .collect() + } + + /// Like `to_compile_error`, but for use in macros that produce items. + #[cfg(all(feature = "serde", any(feature = "formatting", feature = "parsing")))] + pub(crate) fn to_compile_error_standalone(&self) -> TokenStream { + let end = self.span_end(); + self.to_compile_error() + .into_iter() + .chain(std::iter::once( + TokenTree::from(Punct::new(';', Spacing::Alone)).with_span(end), + )) + .collect() + } +} -- cgit v1.2.3