History

avoid another vec allocation by inlining code via closure.

Sebastian Thiel committed 4 years ago

Commit d88952a1 parent 5a55dbf1 file · +18 −14Browse files

Unified · Split

git-pathspec/src/parse.rs+18−14
@@ -94,9 +94,10 @@ fn parse_long_keywords(input: &[u8], p: &mut Pattern, cursor: &mut usize) -> Res · 93 unmodified lines
94 return Ok(());94 return Ok(());
95 }95 }
96 96
97 for keyword in split_on_non_escaped_char(input, b',') {97 split_on_non_escaped_char(input, b',', |keyword| {
98 let attr_prefix = b"attr:";
98 match keyword {99 match keyword {
99 b"attr" => continue,100 b"attr" => {}
100 b"top" => p.signature |= MagicSignature::TOP,101 b"top" => p.signature |= MagicSignature::TOP,
101 b"icase" => p.signature |= MagicSignature::ICASE,102 b"icase" => p.signature |= MagicSignature::ICASE,
102 b"exclude" => p.signature |= MagicSignature::EXCLUDE,103 b"exclude" => p.signature |= MagicSignature::EXCLUDE,
@@ -108,9 +109,9 @@ fn parse_long_keywords(input: &[u8], p: &mut Pattern, cursor: &mut usize) -> Res · 5 unmodified lines
108 MatchMode::Literal => return Err(Error::IncompatibleSearchModes),109 MatchMode::Literal => return Err(Error::IncompatibleSearchModes),
109 _ => p.search_mode = MatchMode::PathAwareGlob,110 _ => p.search_mode = MatchMode::PathAwareGlob,
110 },111 },
111 _ if keyword.starts_with(b"attr:") => {112 _ if keyword.starts_with(attr_prefix) => {
112 if p.attributes.is_empty() {113 if p.attributes.is_empty() {
113 p.attributes = parse_attributes(&keyword[5..])?;114 p.attributes = parse_attributes(&keyword[attr_prefix.len()..])?;
114 } else {115 } else {
115 return Err(Error::MultipleAttributeSpecifications);116 return Err(Error::MultipleAttributeSpecifications);
116 }117 }
@@ -120,25 +121,28 @@ fn parse_long_keywords(input: &[u8], p: &mut Pattern, cursor: &mut usize) -> Res · 3 unmodified lines
120 keyword: BString::from(keyword),121 keyword: BString::from(keyword),
121 });122 });
122 }123 }
123 }124 };
124 }125 Ok(())
125 126 })
126 Ok(())
127}127}
128 128
129fn split_on_non_escaped_char(input: &[u8], split_char: u8) -> Vec<&[u8]> {129fn split_on_non_escaped_char(
130 let mut keywords = Vec::new();130 input: &[u8],
131 split_char: u8,
132 mut f: impl FnMut(&[u8]) -> Result<(), Error>,
133) -> Result<(), Error> {
131 let mut i = 0;134 let mut i = 0;
132 let mut last = 0;135 let mut last = 0;
133 for window in input.windows(2) {136 for window in input.windows(2) {
134 i += 1;137 i += 1;
135 if window[0] != b'\\' && window[1] == split_char {138 if window[0] != b'\\' && window[1] == split_char {
136 keywords.push(&input[last..i]);139 let keyword = &input[last..i];
140 f(keyword)?;
137 last = i + 1;141 last = i + 1;
138 }142 }
139 }143 }
140 keywords.push(&input[last..]);144 let last_keyword = &input[last..];
141 keywords145 f(last_keyword)
142}146}
143 147
144fn parse_attributes(input: &[u8]) -> Result<Vec<git_attributes::Assignment>, Error> {148fn parse_attributes(input: &[u8]) -> Result<Vec<git_attributes::Assignment>, Error> {
@@ -175,7 +179,7 @@ fn unescape_attribute_values(input: &BStr) -> Result<Cow<'_, BStr>, Error> { · 30 unmodified lines
175 match out {179 match out {
176 Cow::Borrowed(_) => {180 Cow::Borrowed(_) => {
177 let end = out.len() + attr.len() + 1;181 let end = out.len() + attr.len() + 1;
178 out = Cow::Borrowed(&input[0..end.min(input.len())])182 out = Cow::Borrowed(&input[0..end.min(input.len())]);
179 }183 }
180 Cow::Owned(_) => {184 Cow::Owned(_) => {
181 let out = out.to_mut();185 let out = out.to_mut();