@@ -10,32 +10,35 @@ pub struct ScriptSource<'s> {
1010
1111impl < ' s > ScriptSource < ' s > {
1212 pub fn parse ( input : & ' s str ) -> CargoResult < Self > {
13+ use winnow:: stream:: FindSlice as _;
14+ use winnow:: stream:: Stream as _;
15+
1316 let mut source = Self {
1417 shebang : None ,
1518 info : None ,
1619 frontmatter : None ,
1720 content : input,
1821 } ;
1922
20- if let Some ( shebang_end) = strip_shebang ( source. content ) {
21- let ( shebang, content) = source. content . split_at ( shebang_end) ;
22- source. shebang = Some ( shebang) ;
23- source. content = content;
24- }
23+ let mut input = winnow:: stream:: LocatingSlice :: new ( input) ;
2524
26- let mut rest = source. content ;
25+ if let Some ( shebang_end) = strip_shebang ( input. as_ref ( ) ) {
26+ source. shebang = Some ( input. next_slice ( shebang_end) ) ;
27+ source. content = input. as_ref ( ) ;
28+ }
2729
2830 // Whitespace may precede a frontmatter but must end with a newline
29- if let Some ( nl_end) = strip_ws_lines ( rest ) {
30- rest = & rest [ nl_end.. ] ;
31+ if let Some ( nl_end) = strip_ws_lines ( input . as_ref ( ) ) {
32+ let _ = input . next_slice ( nl_end ) ;
3133 }
3234
3335 // Opens with a line that starts with 3 or more `-` followed by an optional identifier
3436 const FENCE_CHAR : char = '-' ;
35- let fence_length = rest
37+ let fence_length = input
38+ . as_ref ( )
3639 . char_indices ( )
3740 . find_map ( |( i, c) | ( c != FENCE_CHAR ) . then_some ( i) )
38- . unwrap_or ( rest . len ( ) ) ;
41+ . unwrap_or_else ( || input . eof_offset ( ) ) ;
3942 match fence_length {
4043 0 => {
4144 return Ok ( source) ;
@@ -48,37 +51,40 @@ impl<'s> ScriptSource<'s> {
4851 }
4952 _ => { }
5053 }
51- let ( fence_pattern, rest ) = rest . split_at ( fence_length) ;
52- let Some ( info_end_index ) = rest . find ( '\n' ) else {
54+ let fence_pattern = input . next_slice ( fence_length) ;
55+ let Some ( info_nl ) = input . find_slice ( " \n " ) else {
5356 anyhow:: bail!( "no closing `{fence_pattern}` found for frontmatter" ) ;
5457 } ;
55- let ( info, rest ) = rest . split_at ( info_end_index ) ;
58+ let info = input . next_slice ( info_nl . start ) ;
5659 let info = info. trim_matches ( is_whitespace) ;
5760 if !info. is_empty ( ) {
5861 source. info = Some ( info) ;
5962 }
6063
6164 // Ends with a line that starts with a matching number of `-` only followed by whitespace
6265 let nl_fence_pattern = format ! ( "\n {fence_pattern}" ) ;
63- let Some ( frontmatter_nl) = rest . find ( & nl_fence_pattern) else {
66+ let Some ( frontmatter_nl) = input . find_slice ( nl_fence_pattern. as_str ( ) ) else {
6467 anyhow:: bail!( "no closing `{fence_pattern}` found for frontmatter" ) ;
6568 } ;
66- let frontmatter = & rest [ .. frontmatter_nl + 1 ] ;
69+ let frontmatter = input . next_slice ( frontmatter_nl. start + 1 ) ;
6770 let frontmatter = frontmatter
6871 . strip_prefix ( '\n' )
6972 . expect ( "earlier `found` + `split_at` left us here" ) ;
7073 source. frontmatter = Some ( frontmatter) ;
71- let rest = & rest [ frontmatter_nl + nl_fence_pattern . len ( ) .. ] ;
74+ let _ = input . next_slice ( fence_length ) ;
7275
73- let ( after_closing_fence, rest) = rest. split_once ( "\n " ) . unwrap_or ( ( rest, "" ) ) ;
76+ let nl = input. find_slice ( "\n " ) ;
77+ let after_closing_fence = input. next_slice (
78+ nl. map ( |span| span. end )
79+ . unwrap_or_else ( || input. eof_offset ( ) ) ,
80+ ) ;
7481 let after_closing_fence = after_closing_fence. trim_matches ( is_whitespace) ;
7582 if !after_closing_fence. is_empty ( ) {
7683 // extra characters beyond the original fence pattern, even if they are extra `-`
7784 anyhow:: bail!( "trailing characters found after frontmatter close" ) ;
7885 }
7986
80- let frontmatter_len = input. len ( ) - rest. len ( ) ;
81- source. content = & input[ frontmatter_len..] ;
87+ source. content = input. finish ( ) ;
8288
8389 let repeat = Self :: parse ( source. content ) ?;
8490 if repeat. frontmatter . is_some ( ) {
0 commit comments