| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; |
| use core::fmt::{self, Debug, Formatter}; |
| use core::hash::{Hash, Hasher}; |
| |
| use crate::tokenizer::TokenWithSpan; |
| |
| #[cfg(feature = "serde")] |
| use serde::{Deserialize, Serialize}; |
| |
| #[cfg(feature = "visitor")] |
| use sqlparser_derive::{Visit, VisitMut}; |
| |
| /// A wrapper over [`TokenWithSpan`]s that ignores the token and source |
| /// location in comparisons and hashing. |
| /// |
| /// This type is used when the token and location is not relevant for semantics, |
| /// but is still needed for accurate source location tracking, for example, in |
| /// the nodes in the [ast](crate::ast) module. |
| /// |
| /// Note: **All** `AttachedTokens` are equal. |
| /// |
| /// # Examples |
| /// |
| /// Same token, different location are equal |
| /// ``` |
| /// # use sqlparser::ast::helpers::attached_token::AttachedToken; |
| /// # use sqlparser::tokenizer::{Location, Span, Token, TokenWithLocation}; |
| /// // commas @ line 1, column 10 |
| /// let tok1 = TokenWithLocation::new( |
| /// Token::Comma, |
| /// Span::new(Location::new(1, 10), Location::new(1, 11)), |
| /// ); |
| /// // commas @ line 2, column 20 |
| /// let tok2 = TokenWithLocation::new( |
| /// Token::Comma, |
| /// Span::new(Location::new(2, 20), Location::new(2, 21)), |
| /// ); |
| /// |
| /// assert_ne!(tok1, tok2); // token with locations are *not* equal |
| /// assert_eq!(AttachedToken(tok1), AttachedToken(tok2)); // attached tokens are |
| /// ``` |
| /// |
| /// Different token, different location are equal 🤯 |
| /// |
| /// ``` |
| /// # use sqlparser::ast::helpers::attached_token::AttachedToken; |
| /// # use sqlparser::tokenizer::{Location, Span, Token, TokenWithLocation}; |
| /// // commas @ line 1, column 10 |
| /// let tok1 = TokenWithLocation::new( |
| /// Token::Comma, |
| /// Span::new(Location::new(1, 10), Location::new(1, 11)), |
| /// ); |
| /// // period @ line 2, column 20 |
| /// let tok2 = TokenWithLocation::new( |
| /// Token::Period, |
| /// Span::new(Location::new(2, 10), Location::new(2, 21)), |
| /// ); |
| /// |
| /// assert_ne!(tok1, tok2); // token with locations are *not* equal |
| /// assert_eq!(AttachedToken(tok1), AttachedToken(tok2)); // attached tokens are |
| /// ``` |
| /// // period @ line 2, column 20 |
| #[derive(Clone)] |
| #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] |
| pub struct AttachedToken(pub TokenWithSpan); |
| |
| impl AttachedToken { |
| /// Return a new Empty AttachedToken |
| pub fn empty() -> Self { |
| AttachedToken(TokenWithSpan::new_eof()) |
| } |
| } |
| |
| // Conditional Implementations |
| impl Debug for AttachedToken { |
| fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
| self.0.fmt(f) |
| } |
| } |
| |
| // Blanket Implementations |
| impl PartialEq for AttachedToken { |
| fn eq(&self, _: &Self) -> bool { |
| true |
| } |
| } |
| |
| impl Eq for AttachedToken {} |
| |
| impl PartialOrd for AttachedToken { |
| fn partial_cmp(&self, other: &Self) -> Option<Ordering> { |
| Some(self.cmp(other)) |
| } |
| } |
| |
| impl Ord for AttachedToken { |
| fn cmp(&self, _: &Self) -> Ordering { |
| Ordering::Equal |
| } |
| } |
| |
| impl Hash for AttachedToken { |
| fn hash<H: Hasher>(&self, _state: &mut H) { |
| // Do nothing |
| } |
| } |
| |
| impl From<TokenWithSpan> for AttachedToken { |
| fn from(value: TokenWithSpan) -> Self { |
| AttachedToken(value) |
| } |
| } |
| |
| impl From<AttachedToken> for TokenWithSpan { |
| fn from(value: AttachedToken) -> Self { |
| value.0 |
| } |
| } |