sqlx_models_parser/dialect/
mod.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13mod ansi;
14mod generic;
15mod hive;
16pub mod keywords;
17mod mssql;
18mod mysql;
19mod postgresql;
20mod snowflake;
21mod sqlite;
22
23use core::any::{Any, TypeId};
24use core::fmt::Debug;
25
26pub use self::ansi::AnsiDialect;
27pub use self::generic::GenericDialect;
28pub use self::hive::HiveDialect;
29pub use self::mssql::MsSqlDialect;
30pub use self::mysql::MySqlDialect;
31pub use self::postgresql::PostgreSqlDialect;
32pub use self::snowflake::SnowflakeDialect;
33pub use self::sqlite::SQLiteDialect;
34
35/// `dialect_of!(parser is SQLiteDialect |  GenericDialect)` evaluates
36/// to `true` iff `parser.dialect` is one of the `Dialect`s specified.
37macro_rules! dialect_of {
38    ( $parsed_dialect: ident is $($dialect_type: ty)|+ ) => {
39        ($($parsed_dialect.dialect.is::<$dialect_type>())||+)
40    };
41}
42
43pub trait Dialect: Debug + Any {
44    /// Determine if a character starts a quoted identifier. The default
45    /// implementation, accepting "double quoted" ids is both ANSI-compliant
46    /// and appropriate for most dialects (with the notable exception of
47    /// MySQL, MS SQL, and sqlite). You can accept one of characters listed
48    /// in `Word::matching_end_quote` here
49    fn is_delimited_identifier_start(&self, ch: char) -> bool {
50        ch == '"'
51    }
52    /// Determine if a character is a valid start character for an unquoted identifier
53    fn is_identifier_start(&self, ch: char) -> bool;
54    /// Determine if a character is a valid unquoted identifier character
55    fn is_identifier_part(&self, ch: char) -> bool;
56}
57
58impl dyn Dialect {
59    #[inline]
60    pub fn is<T: Dialect>(&self) -> bool {
61        // borrowed from `Any` implementation
62        TypeId::of::<T>() == self.type_id()
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::ansi::AnsiDialect;
69    use super::generic::GenericDialect;
70    use super::*;
71
72    struct DialectHolder<'a> {
73        dialect: &'a dyn Dialect,
74    }
75
76    #[test]
77    fn test_is_dialect() {
78        let generic_dialect: &dyn Dialect = &GenericDialect {};
79        let ansi_dialect: &dyn Dialect = &AnsiDialect {};
80
81        let generic_holder = DialectHolder {
82            dialect: generic_dialect,
83        };
84        let ansi_holder = DialectHolder {
85            dialect: ansi_dialect,
86        };
87
88        assert!(dialect_of!(generic_holder is GenericDialect |  AnsiDialect),);
89        assert!(!dialect_of!(generic_holder is  AnsiDialect));
90
91        assert!(dialect_of!(ansi_holder is  AnsiDialect));
92        assert!(dialect_of!(ansi_holder is  GenericDialect | AnsiDialect),);
93        assert!(!dialect_of!(ansi_holder is  GenericDialect | MsSqlDialect),);
94    }
95}