@@ -10,32 +10,35 @@ pub struct ScriptSource<'s> {
10
10
11
11
impl < ' s > ScriptSource < ' s > {
12
12
pub fn parse ( input : & ' s str ) -> CargoResult < Self > {
13
+ use winnow:: stream:: FindSlice as _;
14
+ use winnow:: stream:: Stream as _;
15
+
13
16
let mut source = Self {
14
17
shebang : None ,
15
18
info : None ,
16
19
frontmatter : None ,
17
20
content : input,
18
21
} ;
19
22
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) ;
25
24
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
+ }
27
29
28
30
// 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 ) ;
31
33
}
32
34
33
35
// Opens with a line that starts with 3 or more `-` followed by an optional identifier
34
36
const FENCE_CHAR : char = '-' ;
35
- let fence_length = rest
37
+ let fence_length = input
38
+ . as_ref ( )
36
39
. char_indices ( )
37
40
. find_map ( |( i, c) | ( c != FENCE_CHAR ) . then_some ( i) )
38
- . unwrap_or ( rest . len ( ) ) ;
41
+ . unwrap_or_else ( || input . eof_offset ( ) ) ;
39
42
match fence_length {
40
43
0 => {
41
44
return Ok ( source) ;
@@ -48,37 +51,40 @@ impl<'s> ScriptSource<'s> {
48
51
}
49
52
_ => { }
50
53
}
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 {
53
56
anyhow:: bail!( "no closing `{fence_pattern}` found for frontmatter" ) ;
54
57
} ;
55
- let ( info, rest ) = rest . split_at ( info_end_index ) ;
58
+ let info = input . next_slice ( info_nl . start ) ;
56
59
let info = info. trim_matches ( is_whitespace) ;
57
60
if !info. is_empty ( ) {
58
61
source. info = Some ( info) ;
59
62
}
60
63
61
64
// Ends with a line that starts with a matching number of `-` only followed by whitespace
62
65
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 {
64
67
anyhow:: bail!( "no closing `{fence_pattern}` found for frontmatter" ) ;
65
68
} ;
66
- let frontmatter = & rest [ .. frontmatter_nl + 1 ] ;
69
+ let frontmatter = input . next_slice ( frontmatter_nl. start + 1 ) ;
67
70
let frontmatter = frontmatter
68
71
. strip_prefix ( '\n' )
69
72
. expect ( "earlier `found` + `split_at` left us here" ) ;
70
73
source. frontmatter = Some ( frontmatter) ;
71
- let rest = & rest [ frontmatter_nl + nl_fence_pattern . len ( ) .. ] ;
74
+ let _ = input . next_slice ( fence_length ) ;
72
75
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
+ ) ;
74
81
let after_closing_fence = after_closing_fence. trim_matches ( is_whitespace) ;
75
82
if !after_closing_fence. is_empty ( ) {
76
83
// extra characters beyond the original fence pattern, even if they are extra `-`
77
84
anyhow:: bail!( "trailing characters found after frontmatter close" ) ;
78
85
}
79
86
80
- let frontmatter_len = input. len ( ) - rest. len ( ) ;
81
- source. content = & input[ frontmatter_len..] ;
87
+ source. content = input. finish ( ) ;
82
88
83
89
let repeat = Self :: parse ( source. content ) ?;
84
90
if repeat. frontmatter . is_some ( ) {
0 commit comments