@@ -3,67 +3,77 @@ use std::str::Lines;
33use anyhow:: bail;
44
55const RANGE_SEPARATOR : & ' static str = ":" ;
6- const DEFAULT_RANGE : & ' static str = "start:end" ;
6+ pub const DEFAULT_RANGE : & ' static str = "start:end" ;
77
8- fn parse_range_point ( point : & str , lines : & Vec < & str > ) -> anyhow:: Result < usize > {
9- let point = match point {
10- "start" => 0 ,
11- "end" => lines. len ( ) ,
12- _ => point. parse :: < usize > ( ) ?,
13- } ;
8+ pub struct Range ( pub String , pub String ) ;
149
15- Ok ( point)
16- }
10+ impl Range {
11+ // Prepare range string by following rules:
12+ //
13+ // If raw_range is equal to "n:", which means x:end
14+ // If raw_range is equal to ":n", which means start:n
15+ fn prepare_range ( raw_range : & str ) -> String {
16+ if raw_range. starts_with ( RANGE_SEPARATOR ) {
17+ format ! ( "{}{}" , "start" , raw_range)
18+ } else if raw_range. ends_with ( RANGE_SEPARATOR ) {
19+ format ! ( "{}{}" , raw_range, "end" )
20+ } else {
21+ raw_range. to_string ( )
22+ }
23+ }
24+
25+ pub fn from_opt_string ( opt_str : Option < String > ) -> anyhow:: Result < Self > {
26+ Range :: from_str ( & opt_str. unwrap_or ( String :: from ( DEFAULT_RANGE ) ) )
27+ }
1728
18- pub fn cut_code_snippet_by_range (
19- code_snippet : & str ,
20- range : & Option < String > ,
21- ) -> anyhow:: Result < String > {
22- let range = range. clone ( ) . unwrap_or ( String :: from ( DEFAULT_RANGE ) ) ;
23- let range_points = range. split ( RANGE_SEPARATOR ) . collect :: < Vec < _ > > ( ) ;
29+ pub fn from_str ( range_str : & str ) -> anyhow:: Result < Self > {
30+ let range = Range :: prepare_range ( range_str) ;
31+ let range_points = range. split ( RANGE_SEPARATOR ) . collect :: < Vec < _ > > ( ) ;
2432
25- if range_points. len ( ) != 2 {
26- bail ! ( "Invalid range format" ) ;
33+ if range_points. len ( ) != 2 {
34+ bail ! ( "Invalid range format" ) ;
35+ }
36+
37+ Ok ( Range (
38+ range_points[ 0 ] . to_string ( ) ,
39+ range_points[ 1 ] . to_string ( ) ,
40+ ) )
2741 }
2842
29- let code_snippet_lines = code_snippet. lines ( ) ;
30- let ( start, end) = parse_range ( & range_points, & code_snippet_lines) ?;
31- let code_snippet = code_snippet_lines
32- . skip ( start)
33- . take ( end - start)
34- . collect :: < Vec < & str > > ( )
35- . join ( "\n " ) ;
43+ // Parse "start" to 0, "end" to lines.len(), and other values to usize
44+ fn parse_range ( & self , code_snippet_lines : & Lines ) -> anyhow:: Result < ( usize , usize ) > {
45+ let Range ( start, end) = self ;
46+ let lines = code_snippet_lines. clone ( ) . collect :: < Vec < & str > > ( ) ;
47+ let start = parse_range_point ( & start, & lines) ?;
48+ let end = parse_range_point ( & end, & lines) ?;
49+ let points = if start > end {
50+ ( end, start)
51+ } else {
52+ ( start, end)
53+ } ;
3654
37- Ok ( code_snippet )
38- }
55+ Ok ( points )
56+ }
3957
40- // Prepare range string by following rules:
41- //
42- // If raw_range is equal to "n:", which means x:end
43- // If raw_range is equal to ":n", which means start:n
44- pub fn prepare_range ( raw_range : & str ) -> String {
45- if raw_range. starts_with ( RANGE_SEPARATOR ) {
46- format ! ( "{}{}" , "start" , raw_range)
47- } else if raw_range. ends_with ( RANGE_SEPARATOR ) {
48- format ! ( "{}{}" , raw_range, "end" )
49- } else {
50- raw_range. to_string ( )
58+ pub fn cut_code_snippet ( & self , code_snippet : String ) -> anyhow:: Result < String > {
59+ let code_snippet_lines = code_snippet. lines ( ) ;
60+ let ( start, end) = self . parse_range ( & code_snippet_lines) ?;
61+ let code_snippet = code_snippet_lines
62+ . skip ( start)
63+ . take ( end - start)
64+ . collect :: < Vec < & str > > ( )
65+ . join ( "\n " ) ;
66+
67+ Ok ( code_snippet)
5168 }
5269}
5370
54- // Parse "start" to 0, "end" to lines.len(), and other values to usize
55- pub fn parse_range (
56- range_points : & Vec < & str > ,
57- code_snippet_lines : & Lines ,
58- ) -> anyhow:: Result < ( usize , usize ) > {
59- let lines = code_snippet_lines. clone ( ) . collect :: < Vec < & str > > ( ) ;
60- let start = parse_range_point ( range_points[ 0 ] , & lines) ?;
61- let end = parse_range_point ( range_points[ 1 ] , & lines) ?;
62- let points = if start > end {
63- ( end, start)
64- } else {
65- ( start, end)
71+ fn parse_range_point ( point : & str , lines : & Vec < & str > ) -> anyhow:: Result < usize > {
72+ let point = match point {
73+ "start" => 1 ,
74+ "end" => lines. len ( ) ,
75+ _ => point. parse :: < usize > ( ) ?,
6676 } ;
6777
68- Ok ( points )
78+ Ok ( point )
6979}
0 commit comments