Skip to content

Commit f2e803f

Browse files
committed
Work on Comment parsing logic began + support for comment errors
1 parent caa7155 commit f2e803f

2 files changed

Lines changed: 134 additions & 15 deletions

File tree

src/ast.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//! Module for parsing the SQL and then using the resulting AST to walk back and
2-
//! check for comments
1+
//! Module for parsing the SQL and then using the resulting AST that will later
2+
//! be used in `comments` module
33
use std::path::Path;
44

55
use sqlparser::{
@@ -30,12 +30,24 @@ impl ParsedSqlFile {
3030
Ok(Self { file, statements })
3131
}
3232

33+
/// Getter method for returning the [`SqlFile`]
34+
#[must_use]
35+
pub const fn file(&self) -> &SqlFile {
36+
&self.file
37+
}
38+
3339
/// Getter method for returning the current object's file's path
3440
#[must_use]
3541
pub fn path(&self) -> &Path {
3642
self.file.path()
3743
}
3844

45+
/// Getter for the file's content
46+
#[must_use]
47+
pub fn content(&self) -> &str {
48+
self.file.content()
49+
}
50+
3951
/// Getter method for returning the vector of all statements [`Statement`]
4052
#[must_use]
4153
pub fn statements(&self) -> &[Statement] {

src/comments.rs

Lines changed: 120 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
//!
44
//! *leading comment* a comment that
55
//! precedes an SQL Statement.
6+
use std::fmt;
7+
8+
use crate::ast::ParsedSqlFile;
69

710
/// Structure for holding a location in the file. Assumes file is first split by
811
/// lines and then split by characters (column)
12+
#[derive(Debug)]
913
pub struct Location {
1014
line: u64,
1115
column: u64,
@@ -35,14 +39,20 @@ impl Location {
3539
}
3640
}
3741

42+
impl Default for Location {
43+
fn default() -> Self {
44+
Self::new(0, 0)
45+
}
46+
}
47+
3848
/// A structure for holding the span of comments found
39-
pub struct CommentSpan {
49+
pub struct Span {
4050
start: Location,
4151
end: Location,
4252
}
4353

44-
impl CommentSpan {
45-
/// Method for creating a new instance of the [`CommentSpan`] for a
54+
impl Span {
55+
/// Method for creating a new instance of the [`Span`] for a
4656
/// comment's span
4757
///
4858
/// # Parameters
@@ -53,46 +63,119 @@ impl CommentSpan {
5363
Self { start, end }
5464
}
5565

56-
/// Getter for the start location of a [`CommentSpan`]
66+
/// Getter for the start location of a [`Span`]
5767
#[must_use]
5868
pub const fn start(&self) -> &Location {
5969
&self.start
6070
}
6171

62-
/// Getter for the end location of a [`CommentSpan`]
72+
/// Getter for the end location of a [`Span`]
6373
#[must_use]
6474
pub const fn end(&self) -> &Location {
6575
&self.end
6676
}
6777
}
6878

69-
/// Structure that holds the comment along with its location in the file
79+
/// Enum for holding the comment content, differentiated by single line `--` and
80+
/// multiline `/* */`
81+
pub enum CommentKind {
82+
/// Enum variant for Multiline Comments
83+
MultiLine(String),
84+
/// Enum variant for Single Line Comments
85+
SingleLine(String),
86+
}
87+
88+
/// Structure for containing the [`CommentKind`] and the [`Span`] for a comment
7089
pub struct Comment {
71-
comment: String,
72-
span: CommentSpan,
90+
kind: CommentKind,
91+
span: Span,
7392
}
7493

7594
impl Comment {
76-
/// Method for creating a new [`Comment`] from the comment [`String`] and
77-
/// the [`CommentSpan`]
95+
/// Method for making a new comment
96+
///
97+
/// # Parameters
98+
/// - `kind` where the type of comment is passed as a [`CommentKind`]
99+
/// - `span` where the [`Span`] of the comment is passed
100+
#[must_use]
101+
pub const fn new(kind: CommentKind, span: Span) -> Self {
102+
Self { kind, span }
103+
}
104+
105+
/// Getter method to get the [`CommentKind`]
106+
#[must_use]
107+
pub const fn kind(&self) -> &CommentKind {
108+
&self.kind
109+
}
110+
111+
/// Getter method to get the [`Span`] of the comment
112+
#[must_use]
113+
pub const fn span(&self) -> &Span {
114+
&self.span
115+
}
116+
117+
/// Getter method that will return the comment content as a [`str`],
118+
/// regardless of [`CommentKind`]
119+
#[must_use]
120+
pub const fn text(&self) -> &str {
121+
match &self.kind {
122+
CommentKind::SingleLine(s) | CommentKind::MultiLine(s) => s.as_str(),
123+
}
124+
}
125+
}
126+
127+
/// Enum for returning errors withe Comment parsing
128+
#[derive(Debug)]
129+
pub enum CommentError {
130+
/// Found a block terminator `*/` without a matching opener `/*`
131+
UnmatchedBlockCommentStart {
132+
/// Returns the location of the block terminator found
133+
location: Location,
134+
},
135+
}
136+
137+
impl fmt::Display for CommentError {
138+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139+
match self {
140+
CommentError::UnmatchedBlockCommentStart { location } => {
141+
write!(
142+
f,
143+
"unmatched block comment start at line {}, column {}",
144+
location.line(),
145+
location.column()
146+
)
147+
}
148+
}
149+
}
150+
}
151+
152+
/// Structure that holds the comment along with its location in the file
153+
pub struct CommentWithSpan {
154+
comment: Comment,
155+
span: Span,
156+
}
157+
158+
impl CommentWithSpan {
159+
/// Method for creating a new [`CommentWithSpan`] from the comment
160+
/// [`String`] and the [`Span`]
78161
///
79162
/// # Parameters
80163
/// - the comment as a [`String`]
81164
/// - the span of the comment as a [`CommentSpan`]
82165
#[must_use]
83-
pub const fn new(comment: String, span: CommentSpan) -> Self {
166+
pub const fn new(comment: Comment, span: Span) -> Self {
84167
Self { comment, span }
85168
}
86169

87170
/// Getter method for retrieving the comment content
88171
#[must_use]
89-
pub fn comment(&self) -> &str {
172+
pub const fn comment(&self) -> &Comment {
90173
&self.comment
91174
}
92175

93176
/// Getter method for retrieving the [`CommentSpan`] of the comment
94177
#[must_use]
95-
pub const fn span(&self) -> &CommentSpan {
178+
pub const fn span(&self) -> &Span {
96179
&self.span
97180
}
98181
}
@@ -124,6 +207,30 @@ impl Comments {
124207
Self { comments }
125208
}
126209

210+
/// Build all leading comments from a parsed SQL file
211+
#[must_use]
212+
pub fn parse_all_comments_from_file(file: &ParsedSqlFile) -> Self {
213+
let src = file.content();
214+
let mut comments = Vec::new();
215+
let mut current_location = Location::default();
216+
217+
Self { comments }
218+
}
219+
220+
/// Scans the raw file and collects all comments
221+
///
222+
/// # Parameters
223+
/// - `src` which is the `SQL` file content as a [`str`]
224+
fn scan_comments(src: &str) -> Self {
225+
let mut comments = Vec::new();
226+
227+
Self { comments }
228+
}
229+
230+
/// Parse single line comments
231+
232+
/// Parse multi line comments
233+
127234
/// Getter method for retrieving the Vec of [`Comment`]
128235
#[must_use]
129236
pub fn comments(&self) -> &[Comment] {

0 commit comments

Comments
 (0)