@@ -68,17 +68,21 @@ impl<'s> ScriptSource<'s> {
6868 }
6969 1 | 2 => {
7070 // either not a frontmatter or invalid frontmatter opening
71- return Err ( FrontmatterError :: new ( format ! (
72- "found {fence_length} `{FENCE_CHAR}` in rust frontmatter, expected at least 3"
73- ) ) ) ;
71+ return Err ( FrontmatterError :: new (
72+ format ! (
73+ "found {fence_length} `{FENCE_CHAR}` in rust frontmatter, expected at least 3"
74+ ) ,
75+ open_start..open_end,
76+ ) ) ;
7477 }
7578 _ => { }
7679 }
7780 source. open = Some ( open_start..open_end) ;
7881 let Some ( info_nl) = input. find_slice ( "\n " ) else {
79- return Err ( FrontmatterError :: new ( format ! (
80- "no closing `{fence_pattern}` found for frontmatter"
81- ) ) ) ;
82+ return Err ( FrontmatterError :: new (
83+ format ! ( "no closing `{fence_pattern}` found for frontmatter" ) ,
84+ open_start..open_end,
85+ ) ) ;
8286 } ;
8387 let info = input. next_slice ( info_nl. start ) ;
8488 let info = info. trim_matches ( is_whitespace) ;
@@ -91,9 +95,10 @@ impl<'s> ScriptSource<'s> {
9195 // Ends with a line that starts with a matching number of `-` only followed by whitespace
9296 let nl_fence_pattern = format ! ( "\n {fence_pattern}" ) ;
9397 let Some ( frontmatter_nl) = input. find_slice ( nl_fence_pattern. as_str ( ) ) else {
94- return Err ( FrontmatterError :: new ( format ! (
95- "no closing `{fence_pattern}` found for frontmatter"
96- ) ) ) ;
98+ return Err ( FrontmatterError :: new (
99+ format ! ( "no closing `{fence_pattern}` found for frontmatter" ) ,
100+ open_start..open_end,
101+ ) ) ;
97102 } ;
98103 let frontmatter_start = input. current_token_start ( ) + 1 ; // skip nl from infostring
99104 let _ = input. next_slice ( frontmatter_nl. start + 1 ) ;
@@ -113,9 +118,10 @@ impl<'s> ScriptSource<'s> {
113118 let after_closing_fence = after_closing_fence. trim_matches ( is_whitespace) ;
114119 if !after_closing_fence. is_empty ( ) {
115120 // extra characters beyond the original fence pattern, even if they are extra `-`
116- return Err ( FrontmatterError :: new ( format ! (
117- "trailing characters found after frontmatter close"
118- ) ) ) ;
121+ return Err ( FrontmatterError :: new (
122+ format ! ( "trailing characters found after frontmatter close" ) ,
123+ close_end..content_start,
124+ ) ) ;
119125 }
120126
121127 source. content = content_start..content_end;
@@ -129,9 +135,12 @@ impl<'s> ScriptSource<'s> {
129135 . find_map ( |( i, c) | ( c != FENCE_CHAR ) . then_some ( i) )
130136 . unwrap_or_else ( || input. eof_offset ( ) ) ;
131137 if 0 < fence_length {
132- return Err ( FrontmatterError :: new ( format ! (
133- "only one frontmatter is supported"
134- ) ) ) ;
138+ let fence_start = input. current_token_start ( ) ;
139+ let fence_end = fence_start + fence_length;
140+ return Err ( FrontmatterError :: new (
141+ format ! ( "only one frontmatter is supported" ) ,
142+ fence_start..fence_end,
143+ ) ) ;
135144 }
136145
137146 Ok ( source)
@@ -248,14 +257,24 @@ fn is_whitespace(c: char) -> bool {
248257#[ derive( Debug ) ]
249258pub struct FrontmatterError {
250259 message : String ,
260+ span : Span ,
251261}
252262
253263impl FrontmatterError {
254- pub fn new ( message : impl Into < String > ) -> Self {
264+ pub fn new ( message : impl Into < String > , span : Span ) -> Self {
255265 Self {
256266 message : message. into ( ) ,
267+ span,
257268 }
258269 }
270+
271+ pub fn message ( & self ) -> & str {
272+ self . message . as_str ( )
273+ }
274+
275+ pub fn span ( & self ) -> Span {
276+ self . span . clone ( )
277+ }
259278}
260279
261280impl std:: fmt:: Display for FrontmatterError {
0 commit comments