History

refactor (#450)

Sebastian Thiel committed 4 years ago

Commit d37fd041 parent afc0a3d2 files · +112 −113Browse files

Showing the changes to git-refspec/src (2 of 2 files). Show all

Unified · Split

2 files
  1. git-refspec/src/match_group/mod.rs +1 −113
  2. git-refspec/src/match_group/validate.rs +111 −0
git-refspec/src/match_group/mod.rs+1−113
@@ -7,119 +7,7 @@ pub(crate) mod types; · 6 unmodified lines
77 pub use types::{Item, Mapping, Outcome, Source, SourceRef};
88
99 ///
10−pub mod validate {
11− use crate::match_group::{Outcome, Source};
12− use bstr::BString;
13− use std::collections::BTreeMap;
14−
15− /// All possible issues found while validating matched mappings.
16− #[derive(Debug, PartialEq, Eq)]
17− pub enum Issue {
18− /// Multiple sources try to write the same destination.
19− ///
20− /// Note that this issue doesn't take into consideration that these sources might contain the same object behind a reference.
21− Conflict {
22− /// The unenforced full name of the reference to be written.
23− destination_full_ref_name: BString,
24− /// The list of sources that map to this destination.
25− sources: Vec<Source>,
26− /// The list of specs that caused the mapping conflict, each matching the respective one in `sources` to allow both
27− /// `sources` and `specs` to be zipped together.
28− specs: Vec<BString>,
29− },
30− }
31−
32− impl std::fmt::Display for Issue {
33− fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34− match self {
35− Issue::Conflict {
36− destination_full_ref_name,
37− sources,
38− specs,
39− } => {
40− write!(
41− f,
42− "Conflicting destination {destination_full_ref_name:?} would be written by {}",
43− sources
44− .iter()
45− .zip(specs.iter())
46− .map(|(src, spec)| format!("{src} ({spec:?})"))
47− .collect::<Vec<_>>()
48− .join(", ")
49− )
50− }
51− }
52− }
53− }
54−
55− /// All possible fixes corrected while validating matched mappings.
56− #[derive(Debug, PartialEq, Eq)]
57− pub enum Fix {}
58−
59− /// The error returned [outcome validation][Outcome::validated()].
60− #[derive(Debug)]
61− pub struct Error {
62− /// All issues discovered during validation.
63− pub issues: Vec<Issue>,
64− }
65−
66− impl std::fmt::Display for Error {
67− fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68− write!(
69− f,
70− "Found {} {} the refspec mapping to be used: \n\t{}",
71− self.issues.len(),
72− (self.issues.len() == 1)
73− .then(|| "issue that prevents")
74− .unwrap_or("issues that prevent"),
75− self.issues
76− .iter()
77− .map(|issue| issue.to_string())
78− .collect::<Vec<_>>()
79− .join("\n\t")
80− )
81− }
82− }
83−
84− impl std::error::Error for Error {}
85−
86− impl<'spec, 'item> Outcome<'spec, 'item> {
87− /// Validate all mappings or dissolve them into an error stating the discovered issues.
88− /// Return `(modified self, issues)` providing a fixed-up set of mappings in `self` with the fixed `issues`
89− /// provided as part of it.
90− /// Terminal issues are communicated using the [`Error`] type accordingly.
91− pub fn validated(self) -> Result<(Self, Vec<Fix>), Error> {
92− let fixed = Vec::new();
93− let mut sources_by_destinations = BTreeMap::new();
94− for (dst, (spec_index, src)) in self
95− .mappings
96− .iter()
97− .filter_map(|m| m.rhs.as_ref().map(|dst| (dst.as_ref(), (m.spec_index, &m.lhs))))
98− {
99− let sources = sources_by_destinations.entry(dst).or_insert_with(Vec::new);
100− if !sources.iter().any(|(_, lhs)| lhs == &src) {
101− sources.push((spec_index, src))
102− }
103− }
104− let mut issues = Vec::new();
105− for (dst, conflicting_sources) in sources_by_destinations.into_iter().filter(|(_, v)| v.len() > 1) {
106− issues.push(Issue::Conflict {
107− destination_full_ref_name: dst.to_owned(),
108− specs: conflicting_sources
109− .iter()
110− .map(|(spec_idx, _)| self.group.specs[*spec_idx].to_bstring())
111− .collect(),
112− sources: conflicting_sources.into_iter().map(|(_, src)| src.to_owned()).collect(),
113− })
114− }
115− if !issues.is_empty() {
116− Err(Error { issues })
117− } else {
118− Ok((self, fixed))
119− }
120− }
121− }
122−}
10+pub mod validate;
12311
12412 /// Initialization
12513 impl<'a> MatchGroup<'a> {
git-refspec/src/match_group/validate.rs+111−0
@@ -0,0 +1,111 @@
1+use crate::match_group::{Outcome, Source};
2+use bstr::BString;
3+use std::collections::BTreeMap;
4+
5+/// All possible issues found while validating matched mappings.
6+#[derive(Debug, PartialEq, Eq)]
7+pub enum Issue {
8+ /// Multiple sources try to write the same destination.
9+ ///
10+ /// Note that this issue doesn't take into consideration that these sources might contain the same object behind a reference.
11+ Conflict {
12+ /// The unenforced full name of the reference to be written.
13+ destination_full_ref_name: BString,
14+ /// The list of sources that map to this destination.
15+ sources: Vec<Source>,
16+ /// The list of specs that caused the mapping conflict, each matching the respective one in `sources` to allow both
17+ /// `sources` and `specs` to be zipped together.
18+ specs: Vec<BString>,
19+ },
20+}
21+
22+impl std::fmt::Display for Issue {
23+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24+ match self {
25+ Issue::Conflict {
26+ destination_full_ref_name,
27+ sources,
28+ specs,
29+ } => {
30+ write!(
31+ f,
32+ "Conflicting destination {destination_full_ref_name:?} would be written by {}",
33+ sources
34+ .iter()
35+ .zip(specs.iter())
36+ .map(|(src, spec)| format!("{src} ({spec:?})"))
37+ .collect::<Vec<_>>()
38+ .join(", ")
39+ )
40+ }
41+ }
42+ }
43+}
44+
45+/// All possible fixes corrected while validating matched mappings.
46+#[derive(Debug, PartialEq, Eq)]
47+pub enum Fix {}
48+
49+/// The error returned [outcome validation][Outcome::validated()].
50+#[derive(Debug)]
51+pub struct Error {
52+ /// All issues discovered during validation.
53+ pub issues: Vec<Issue>,
54+}
55+
56+impl std::fmt::Display for Error {
57+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58+ write!(
59+ f,
60+ "Found {} {} the refspec mapping to be used: \n\t{}",
61+ self.issues.len(),
62+ (self.issues.len() == 1)
63+ .then(|| "issue that prevents")
64+ .unwrap_or("issues that prevent"),
65+ self.issues
66+ .iter()
67+ .map(|issue| issue.to_string())
68+ .collect::<Vec<_>>()
69+ .join("\n\t")
70+ )
71+ }
72+}
73+
74+impl std::error::Error for Error {}
75+
76+impl<'spec, 'item> Outcome<'spec, 'item> {
77+ /// Validate all mappings or dissolve them into an error stating the discovered issues.
78+ /// Return `(modified self, issues)` providing a fixed-up set of mappings in `self` with the fixed `issues`
79+ /// provided as part of it.
80+ /// Terminal issues are communicated using the [`Error`] type accordingly.
81+ pub fn validated(self) -> Result<(Self, Vec<Fix>), Error> {
82+ let fixed = Vec::new();
83+ let mut sources_by_destinations = BTreeMap::new();
84+ for (dst, (spec_index, src)) in self
85+ .mappings
86+ .iter()
87+ .filter_map(|m| m.rhs.as_ref().map(|dst| (dst.as_ref(), (m.spec_index, &m.lhs))))
88+ {
89+ let sources = sources_by_destinations.entry(dst).or_insert_with(Vec::new);
90+ if !sources.iter().any(|(_, lhs)| lhs == &src) {
91+ sources.push((spec_index, src))
92+ }
93+ }
94+ let mut issues = Vec::new();
95+ for (dst, conflicting_sources) in sources_by_destinations.into_iter().filter(|(_, v)| v.len() > 1) {
96+ issues.push(Issue::Conflict {
97+ destination_full_ref_name: dst.to_owned(),
98+ specs: conflicting_sources
99+ .iter()
100+ .map(|(spec_idx, _)| self.group.specs[*spec_idx].to_bstring())
101+ .collect(),
102+ sources: conflicting_sources.into_iter().map(|(_, src)| src.to_owned()).collect(),
103+ })
104+ }
105+ if !issues.is_empty() {
106+ Err(Error { issues })
107+ } else {
108+ Ok((self, fixed))
109+ }
110+ }
111+}