Skip to content

Commit ce0c5f1

Browse files
carols10centsDylan-DPC
authored andcommitted
Another refactoring in links.rs (#1001)
* Extract the concept of a link having a range or anchor specified So that other kinds of links can use this concept too. * Extract a function for parsing range or anchor
1 parent 33d7e86 commit ce0c5f1

File tree

1 file changed

+119
-53
lines changed

1 file changed

+119
-53
lines changed

src/preprocess/links.rs

+119-53
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,16 @@ where
102102
#[derive(PartialEq, Debug, Clone)]
103103
enum LinkType<'a> {
104104
Escaped,
105-
IncludeRange(PathBuf, LineRange),
106-
IncludeAnchor(PathBuf, String),
105+
Include(PathBuf, RangeOrAnchor),
107106
Playpen(PathBuf, Vec<&'a str>),
108107
}
109108

109+
#[derive(PartialEq, Debug, Clone)]
110+
enum RangeOrAnchor {
111+
Range(LineRange),
112+
Anchor(String),
113+
}
114+
110115
// A range of lines specified with some include directive.
111116
#[derive(PartialEq, Debug, Clone)]
112117
enum LineRange {
@@ -165,8 +170,7 @@ impl<'a> LinkType<'a> {
165170
let base = base.as_ref();
166171
match self {
167172
LinkType::Escaped => None,
168-
LinkType::IncludeRange(p, _) => Some(return_relative_path(base, &p)),
169-
LinkType::IncludeAnchor(p, _) => Some(return_relative_path(base, &p)),
173+
LinkType::Include(p, _) => Some(return_relative_path(base, &p)),
170174
LinkType::Playpen(p, _) => Some(return_relative_path(base, &p)),
171175
}
172176
}
@@ -179,9 +183,8 @@ fn return_relative_path<P: AsRef<Path>>(base: P, relative: P) -> PathBuf {
179183
.to_path_buf()
180184
}
181185

182-
fn parse_include_path(path: &str) -> LinkType<'static> {
183-
let mut parts = path.splitn(4, ':').fuse();
184-
let path = parts.next().unwrap().into();
186+
fn parse_range_or_anchor(parts: Option<&str>) -> RangeOrAnchor {
187+
let mut parts = parts.unwrap_or("").splitn(3, ':').fuse();
185188

186189
let next_element = parts.next();
187190
let start = if let Some(value) = next_element.and_then(|s| s.parse::<usize>().ok()) {
@@ -190,7 +193,7 @@ fn parse_include_path(path: &str) -> LinkType<'static> {
190193
} else if let Some("") = next_element {
191194
None
192195
} else if let Some(anchor) = next_element {
193-
return LinkType::IncludeAnchor(path, String::from(anchor));
196+
return RangeOrAnchor::Anchor(String::from(anchor));
194197
} else {
195198
None
196199
};
@@ -202,16 +205,23 @@ fn parse_include_path(path: &str) -> LinkType<'static> {
202205
let end = end.map(|s| s.parse::<usize>());
203206

204207
match (start, end) {
205-
(Some(start), Some(Ok(end))) => LinkType::IncludeRange(path, LineRange::from(start..end)),
206-
(Some(start), Some(Err(_))) => LinkType::IncludeRange(path, LineRange::from(start..)),
207-
(Some(start), None) => LinkType::IncludeRange(path, LineRange::from(start..start + 1)),
208-
(None, Some(Ok(end))) => LinkType::IncludeRange(path, LineRange::from(..end)),
209-
(None, None) | (None, Some(Err(_))) => {
210-
LinkType::IncludeRange(path, LineRange::from(RangeFull))
211-
}
208+
(Some(start), Some(Ok(end))) => RangeOrAnchor::Range(LineRange::from(start..end)),
209+
(Some(start), Some(Err(_))) => RangeOrAnchor::Range(LineRange::from(start..)),
210+
(Some(start), None) => RangeOrAnchor::Range(LineRange::from(start..start + 1)),
211+
(None, Some(Ok(end))) => RangeOrAnchor::Range(LineRange::from(..end)),
212+
(None, None) | (None, Some(Err(_))) => RangeOrAnchor::Range(LineRange::from(RangeFull)),
212213
}
213214
}
214215

216+
fn parse_include_path(path: &str) -> LinkType<'static> {
217+
let mut parts = path.splitn(2, ':');
218+
219+
let path = parts.next().unwrap().into();
220+
let range_or_anchor = parse_range_or_anchor(parts.next());
221+
222+
LinkType::Include(path, range_or_anchor)
223+
}
224+
215225
#[derive(PartialEq, Debug, Clone)]
216226
struct Link<'a> {
217227
start_index: usize,
@@ -255,24 +265,14 @@ impl<'a> Link<'a> {
255265
match self.link_type {
256266
// omit the escape char
257267
LinkType::Escaped => Ok((&self.link_text[1..]).to_owned()),
258-
LinkType::IncludeRange(ref pat, ref range) => {
268+
LinkType::Include(ref pat, ref range_or_anchor) => {
259269
let target = base.join(pat);
260270

261271
fs::read_to_string(&target)
262-
.map(|s| take_lines(&s, range.clone()))
263-
.chain_err(|| {
264-
format!(
265-
"Could not read file for link {} ({})",
266-
self.link_text,
267-
target.display(),
268-
)
272+
.map(|s| match range_or_anchor {
273+
RangeOrAnchor::Range(range) => take_lines(&s, range.clone()),
274+
RangeOrAnchor::Anchor(anchor) => take_anchored_lines(&s, anchor),
269275
})
270-
}
271-
LinkType::IncludeAnchor(ref pat, ref anchor) => {
272-
let target = base.join(pat);
273-
274-
fs::read_to_string(&target)
275-
.map(|s| take_anchored_lines(&s, anchor))
276276
.chain_err(|| {
277277
format!(
278278
"Could not read file for link {} ({})",
@@ -419,7 +419,10 @@ mod tests {
419419
vec![Link {
420420
start_index: 22,
421421
end_index: 48,
422-
link_type: LinkType::IncludeRange(PathBuf::from("file.rs"), LineRange::from(9..20)),
422+
link_type: LinkType::Include(
423+
PathBuf::from("file.rs"),
424+
RangeOrAnchor::Range(LineRange::from(9..20))
425+
),
423426
link_text: "{{#include file.rs:10:20}}",
424427
}]
425428
);
@@ -435,7 +438,10 @@ mod tests {
435438
vec![Link {
436439
start_index: 22,
437440
end_index: 45,
438-
link_type: LinkType::IncludeRange(PathBuf::from("file.rs"), LineRange::from(9..10)),
441+
link_type: LinkType::Include(
442+
PathBuf::from("file.rs"),
443+
RangeOrAnchor::Range(LineRange::from(9..10))
444+
),
439445
link_text: "{{#include file.rs:10}}",
440446
}]
441447
);
@@ -451,7 +457,10 @@ mod tests {
451457
vec![Link {
452458
start_index: 22,
453459
end_index: 46,
454-
link_type: LinkType::IncludeRange(PathBuf::from("file.rs"), LineRange::from(9..)),
460+
link_type: LinkType::Include(
461+
PathBuf::from("file.rs"),
462+
RangeOrAnchor::Range(LineRange::from(9..))
463+
),
455464
link_text: "{{#include file.rs:10:}}",
456465
}]
457466
);
@@ -467,7 +476,10 @@ mod tests {
467476
vec![Link {
468477
start_index: 22,
469478
end_index: 46,
470-
link_type: LinkType::IncludeRange(PathBuf::from("file.rs"), LineRange::from(..20)),
479+
link_type: LinkType::Include(
480+
PathBuf::from("file.rs"),
481+
RangeOrAnchor::Range(LineRange::from(..20))
482+
),
471483
link_text: "{{#include file.rs::20}}",
472484
}]
473485
);
@@ -483,7 +495,10 @@ mod tests {
483495
vec![Link {
484496
start_index: 22,
485497
end_index: 44,
486-
link_type: LinkType::IncludeRange(PathBuf::from("file.rs"), LineRange::from(..)),
498+
link_type: LinkType::Include(
499+
PathBuf::from("file.rs"),
500+
RangeOrAnchor::Range(LineRange::from(..))
501+
),
487502
link_text: "{{#include file.rs::}}",
488503
}]
489504
);
@@ -499,7 +514,10 @@ mod tests {
499514
vec![Link {
500515
start_index: 22,
501516
end_index: 42,
502-
link_type: LinkType::IncludeRange(PathBuf::from("file.rs"), LineRange::from(..)),
517+
link_type: LinkType::Include(
518+
PathBuf::from("file.rs"),
519+
RangeOrAnchor::Range(LineRange::from(..))
520+
),
503521
link_text: "{{#include file.rs}}",
504522
}]
505523
);
@@ -515,9 +533,9 @@ mod tests {
515533
vec![Link {
516534
start_index: 22,
517535
end_index: 49,
518-
link_type: LinkType::IncludeAnchor(
536+
link_type: LinkType::Include(
519537
PathBuf::from("file.rs"),
520-
String::from("anchor")
538+
RangeOrAnchor::Anchor(String::from("anchor"))
521539
),
522540
link_text: "{{#include file.rs:anchor}}",
523541
}]
@@ -585,7 +603,10 @@ mod tests {
585603
Link {
586604
start_index: 38,
587605
end_index: 58,
588-
link_type: LinkType::IncludeRange(PathBuf::from("file.rs"), LineRange::from(..)),
606+
link_type: LinkType::Include(
607+
PathBuf::from("file.rs"),
608+
RangeOrAnchor::Range(LineRange::from(..))
609+
),
589610
link_text: "{{#include file.rs}}",
590611
}
591612
);
@@ -617,7 +638,10 @@ mod tests {
617638
let link_type = parse_include_path("arbitrary");
618639
assert_eq!(
619640
link_type,
620-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(RangeFull))
641+
LinkType::Include(
642+
PathBuf::from("arbitrary"),
643+
RangeOrAnchor::Range(LineRange::from(RangeFull))
644+
)
621645
);
622646
}
623647

@@ -626,7 +650,10 @@ mod tests {
626650
let link_type = parse_include_path("arbitrary:");
627651
assert_eq!(
628652
link_type,
629-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(RangeFull))
653+
LinkType::Include(
654+
PathBuf::from("arbitrary"),
655+
RangeOrAnchor::Range(LineRange::from(RangeFull))
656+
)
630657
);
631658
}
632659

@@ -635,7 +662,10 @@ mod tests {
635662
let link_type = parse_include_path("arbitrary::");
636663
assert_eq!(
637664
link_type,
638-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(RangeFull))
665+
LinkType::Include(
666+
PathBuf::from("arbitrary"),
667+
RangeOrAnchor::Range(LineRange::from(RangeFull))
668+
)
639669
);
640670
}
641671

@@ -644,7 +674,10 @@ mod tests {
644674
let link_type = parse_include_path("arbitrary::NaN");
645675
assert_eq!(
646676
link_type,
647-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(RangeFull))
677+
LinkType::Include(
678+
PathBuf::from("arbitrary"),
679+
RangeOrAnchor::Range(LineRange::from(RangeFull))
680+
)
648681
);
649682
}
650683

@@ -653,7 +686,10 @@ mod tests {
653686
let link_type = parse_include_path("arbitrary:5");
654687
assert_eq!(
655688
link_type,
656-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(4..5))
689+
LinkType::Include(
690+
PathBuf::from("arbitrary"),
691+
RangeOrAnchor::Range(LineRange::from(4..5))
692+
)
657693
);
658694
}
659695

@@ -662,7 +698,10 @@ mod tests {
662698
let link_type = parse_include_path("arbitrary:1");
663699
assert_eq!(
664700
link_type,
665-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(0..1))
701+
LinkType::Include(
702+
PathBuf::from("arbitrary"),
703+
RangeOrAnchor::Range(LineRange::from(0..1))
704+
)
666705
);
667706
}
668707

@@ -671,7 +710,10 @@ mod tests {
671710
let link_type = parse_include_path("arbitrary:0");
672711
assert_eq!(
673712
link_type,
674-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(0..1))
713+
LinkType::Include(
714+
PathBuf::from("arbitrary"),
715+
RangeOrAnchor::Range(LineRange::from(0..1))
716+
)
675717
);
676718
}
677719

@@ -680,7 +722,10 @@ mod tests {
680722
let link_type = parse_include_path("arbitrary:5:");
681723
assert_eq!(
682724
link_type,
683-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(4..))
725+
LinkType::Include(
726+
PathBuf::from("arbitrary"),
727+
RangeOrAnchor::Range(LineRange::from(4..))
728+
)
684729
);
685730
}
686731

@@ -689,7 +734,10 @@ mod tests {
689734
let link_type = parse_include_path("arbitrary:5:NaN");
690735
assert_eq!(
691736
link_type,
692-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(4..))
737+
LinkType::Include(
738+
PathBuf::from("arbitrary"),
739+
RangeOrAnchor::Range(LineRange::from(4..))
740+
)
693741
);
694742
}
695743

@@ -698,7 +746,10 @@ mod tests {
698746
let link_type = parse_include_path("arbitrary::5");
699747
assert_eq!(
700748
link_type,
701-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(..5))
749+
LinkType::Include(
750+
PathBuf::from("arbitrary"),
751+
RangeOrAnchor::Range(LineRange::from(..5))
752+
)
702753
);
703754
}
704755

@@ -707,7 +758,10 @@ mod tests {
707758
let link_type = parse_include_path("arbitrary:5:10");
708759
assert_eq!(
709760
link_type,
710-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(4..10))
761+
LinkType::Include(
762+
PathBuf::from("arbitrary"),
763+
RangeOrAnchor::Range(LineRange::from(4..10))
764+
)
711765
);
712766
}
713767

@@ -716,7 +770,10 @@ mod tests {
716770
let link_type = parse_include_path("arbitrary:-5");
717771
assert_eq!(
718772
link_type,
719-
LinkType::IncludeAnchor(PathBuf::from("arbitrary"), "-5".to_string())
773+
LinkType::Include(
774+
PathBuf::from("arbitrary"),
775+
RangeOrAnchor::Anchor("-5".to_string())
776+
)
720777
);
721778
}
722779

@@ -725,7 +782,10 @@ mod tests {
725782
let link_type = parse_include_path("arbitrary:-5.7");
726783
assert_eq!(
727784
link_type,
728-
LinkType::IncludeAnchor(PathBuf::from("arbitrary"), "-5.7".to_string())
785+
LinkType::Include(
786+
PathBuf::from("arbitrary"),
787+
RangeOrAnchor::Anchor("-5.7".to_string())
788+
)
729789
);
730790
}
731791

@@ -734,7 +794,10 @@ mod tests {
734794
let link_type = parse_include_path("arbitrary:some-anchor:this-gets-ignored");
735795
assert_eq!(
736796
link_type,
737-
LinkType::IncludeAnchor(PathBuf::from("arbitrary"), "some-anchor".to_string())
797+
LinkType::Include(
798+
PathBuf::from("arbitrary"),
799+
RangeOrAnchor::Anchor("some-anchor".to_string())
800+
)
738801
);
739802
}
740803

@@ -743,7 +806,10 @@ mod tests {
743806
let link_type = parse_include_path("arbitrary:5:10:17:anything:");
744807
assert_eq!(
745808
link_type,
746-
LinkType::IncludeRange(PathBuf::from("arbitrary"), LineRange::from(4..10))
809+
LinkType::Include(
810+
PathBuf::from("arbitrary"),
811+
RangeOrAnchor::Range(LineRange::from(4..10))
812+
)
747813
);
748814
}
749815
}

0 commit comments

Comments
 (0)