@@ -4,6 +4,28 @@ use std::fmt::Debug;
44use std:: ops:: Range ;
55use std:: { borrow:: Borrow , ops:: Deref } ;
66
7+ /// Represents a database object (table, function, etc.)
8+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
9+ pub struct DatabaseObject < ' a > {
10+ /// Optional schema name
11+ pub schema : Option < & ' a str > ,
12+ /// Object name (required)
13+ pub name : & ' a str ,
14+ /// Optional object type (e.g., "table", "function", "view")
15+ pub object_type : Option < & ' a str > ,
16+ }
17+
18+ /// Owned version of DatabaseObject for use in diagnostic structs
19+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
20+ pub struct DatabaseObjectOwned {
21+ /// Optional schema name
22+ pub schema : Option < String > ,
23+ /// Object name (required)
24+ pub name : String ,
25+ /// Optional object type (e.g., "table", "function", "view")
26+ pub object_type : Option < String > ,
27+ }
28+
729/// Represents the location of a diagnostic in a resource.
830#[ derive( Debug , Default , Clone , Copy ) ]
931pub struct Location < ' a > {
@@ -12,6 +34,8 @@ pub struct Location<'a> {
1234 /// An optional range of text within the resource associated with the
1335 /// diagnostic.
1436 pub span : Option < TextRange > ,
37+ /// An optional database object reference
38+ pub database_object : Option < DatabaseObject < ' a > > ,
1539 /// The optional source code of the resource.
1640 pub source_code : Option < BorrowedSourceCode < ' a > > ,
1741}
@@ -23,6 +47,7 @@ impl<'a> Location<'a> {
2347 resource : None ,
2448 span : None ,
2549 source_code : None ,
50+ database_object : None ,
2651 }
2752 }
2853}
@@ -42,6 +67,8 @@ impl Eq for Location<'_> {}
4267#[ cfg_attr( feature = "schema" , derive( schemars:: JsonSchema ) ) ]
4368#[ serde( rename_all = "camelCase" ) ]
4469pub enum Resource < Path > {
70+ /// The diagnostic is related to the database and its schema.
71+ Database ,
4572 /// The diagnostic is related to the content of the command line arguments.
4673 Argv ,
4774 /// The diagnostic is related to the content of a memory buffer.
@@ -70,6 +97,7 @@ impl<P> Resource<P> {
7097 P : Deref ,
7198 {
7299 match self {
100+ Resource :: Database => Resource :: Database ,
73101 Resource :: Argv => Resource :: Argv ,
74102 Resource :: Memory => Resource :: Memory ,
75103 Resource :: File ( file) => Resource :: File ( file) ,
@@ -81,6 +109,7 @@ impl Resource<&'_ str> {
81109 /// Converts a `Path<&str>` to `Path<String>`.
82110 pub fn to_owned ( self ) -> Resource < String > {
83111 match self {
112+ Resource :: Database => Resource :: Database ,
84113 Resource :: Argv => Resource :: Argv ,
85114 Resource :: Memory => Resource :: Memory ,
86115 Resource :: File ( file) => Resource :: File ( file. to_owned ( ) ) ,
@@ -194,6 +223,7 @@ pub struct LocationBuilder<'a> {
194223 resource : Option < Resource < & ' a str > > ,
195224 span : Option < TextRange > ,
196225 source_code : Option < BorrowedSourceCode < ' a > > ,
226+ database_object : Option < DatabaseObject < ' a > > ,
197227}
198228
199229impl < ' a > LocationBuilder < ' a > {
@@ -212,11 +242,17 @@ impl<'a> LocationBuilder<'a> {
212242 self
213243 }
214244
245+ pub fn database_object < D : AsDatabaseObject > ( mut self , database_object : & ' a D ) -> Self {
246+ self . database_object = database_object. as_database_object ( ) ;
247+ self
248+ }
249+
215250 pub fn build ( self ) -> Location < ' a > {
216251 Location {
217252 resource : self . resource ,
218253 span : self . span ,
219254 source_code : self . source_code ,
255+ database_object : self . database_object ,
220256 }
221257 }
222258}
@@ -342,6 +378,39 @@ impl AsSourceCode for String {
342378 }
343379}
344380
381+ /// Utility trait for types that can be converted into a database object reference
382+ pub trait AsDatabaseObject {
383+ fn as_database_object ( & self ) -> Option < DatabaseObject < ' _ > > ;
384+ }
385+
386+ impl < T : AsDatabaseObject > AsDatabaseObject for Option < T > {
387+ fn as_database_object ( & self ) -> Option < DatabaseObject < ' _ > > {
388+ self . as_ref ( ) . and_then ( T :: as_database_object)
389+ }
390+ }
391+
392+ impl < T : AsDatabaseObject + ?Sized > AsDatabaseObject for & ' _ T {
393+ fn as_database_object ( & self ) -> Option < DatabaseObject < ' _ > > {
394+ T :: as_database_object ( * self )
395+ }
396+ }
397+
398+ impl < ' a > AsDatabaseObject for DatabaseObject < ' a > {
399+ fn as_database_object ( & self ) -> Option < DatabaseObject < ' _ > > {
400+ Some ( * self )
401+ }
402+ }
403+
404+ impl AsDatabaseObject for DatabaseObjectOwned {
405+ fn as_database_object ( & self ) -> Option < DatabaseObject < ' _ > > {
406+ Some ( DatabaseObject {
407+ schema : self . schema . as_deref ( ) ,
408+ name : & self . name ,
409+ object_type : self . object_type . as_deref ( ) ,
410+ } )
411+ }
412+ }
413+
345414#[ cfg( test) ]
346415mod tests {
347416 use pgls_text_size:: TextSize ;
0 commit comments