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 ) ]
913pub 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
7089pub struct Comment {
71- comment : String ,
72- span : CommentSpan ,
90+ kind : CommentKind ,
91+ span : Span ,
7392}
7493
7594impl 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