Skip to content

Commit 53309be

Browse files
committed
Refactor iterating parsing so error wrapping knows where left off
1 parent f633f9e commit 53309be

File tree

2 files changed

+49
-57
lines changed

2 files changed

+49
-57
lines changed

gix-object/src/commit/ref_iter.rs

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -154,44 +154,40 @@ fn missing_field() -> crate::decode::Error {
154154

155155
impl<'a> CommitRefIter<'a> {
156156
#[inline]
157-
fn next_inner(i: &'a [u8], state: &mut State) -> Result<(&'a [u8], Token<'a>), crate::decode::Error> {
158-
Self::next_inner_(i, state).map_err(crate::decode::Error::with_err)
157+
fn next_inner(mut i: &'a [u8], state: &mut State) -> Result<(&'a [u8], Token<'a>), crate::decode::Error> {
158+
let input = &mut i;
159+
let token = Self::next_inner_(input, state).map_err(crate::decode::Error::with_err)?;
160+
Ok((input, token))
159161
}
160162

161163
fn next_inner_(
162-
mut i: &'a [u8],
164+
input: &mut &'a [u8],
163165
state: &mut State,
164-
) -> Result<(&'a [u8], Token<'a>), winnow::error::ErrMode<crate::decode::ParseError>> {
166+
) -> Result<Token<'a>, winnow::error::ErrMode<crate::decode::ParseError>> {
165167
use State::*;
166168
Ok(match state {
167169
Tree => {
168170
let tree = (|i: &mut _| parse::header_field(i, b"tree", parse::hex_hash))
169171
.context(StrContext::Expected("tree <40 lowercase hex char>".into()))
170-
.parse_next(&mut i)?;
172+
.parse_next(input)?;
171173
*state = State::Parents;
172-
(
173-
i,
174-
Token::Tree {
175-
id: ObjectId::from_hex(tree).expect("parsing validation"),
176-
},
177-
)
174+
Token::Tree {
175+
id: ObjectId::from_hex(tree).expect("parsing validation"),
176+
}
178177
}
179178
Parents => {
180179
let parent = opt(|i: &mut _| parse::header_field(i, b"parent", parse::hex_hash))
181180
.context(StrContext::Expected("commit <40 lowercase hex char>".into()))
182-
.parse_next(&mut i)?;
181+
.parse_next(input)?;
183182
match parent {
184-
Some(parent) => (
185-
i,
186-
Token::Parent {
187-
id: ObjectId::from_hex(parent).expect("parsing validation"),
188-
},
189-
),
183+
Some(parent) => Token::Parent {
184+
id: ObjectId::from_hex(parent).expect("parsing validation"),
185+
},
190186
None => {
191187
*state = State::Signature {
192188
of: SignatureKind::Author,
193189
};
194-
return Self::next_inner_(i, state);
190+
Self::next_inner_(input, state)?
195191
}
196192
}
197193
}
@@ -209,23 +205,20 @@ impl<'a> CommitRefIter<'a> {
209205
};
210206
let signature = (|i: &mut _| parse::header_field(i, field_name, parse::signature))
211207
.context(StrContext::Expected(err_msg.into()))
212-
.parse_next(&mut i)?;
213-
(
214-
i,
215-
match who {
216-
SignatureKind::Author => Token::Author { signature },
217-
SignatureKind::Committer => Token::Committer { signature },
218-
},
219-
)
208+
.parse_next(input)?;
209+
match who {
210+
SignatureKind::Author => Token::Author { signature },
211+
SignatureKind::Committer => Token::Committer { signature },
212+
}
220213
}
221214
Encoding => {
222215
let encoding = opt(|i: &mut _| parse::header_field(i, b"encoding", take_till1(NL)))
223216
.context(StrContext::Expected("encoding <encoding>".into()))
224-
.parse_next(&mut i)?;
217+
.parse_next(input)?;
225218
*state = State::ExtraHeaders;
226219
match encoding {
227-
Some(encoding) => (i, Token::Encoding(encoding.as_bstr())),
228-
None => return Self::next_inner_(i, state),
220+
Some(encoding) => Token::Encoding(encoding.as_bstr()),
221+
None => Self::next_inner_(input, state)?,
229222
}
230223
}
231224
ExtraHeaders => {
@@ -237,22 +230,22 @@ impl<'a> CommitRefIter<'a> {
237230
},
238231
)))
239232
.context(StrContext::Expected("<field> <single-line|multi-line>".into()))
240-
.parse_next(&mut i)?;
233+
.parse_next(input)?;
241234
match extra_header {
242-
Some(extra_header) => (i, Token::ExtraHeader(extra_header)),
235+
Some(extra_header) => Token::ExtraHeader(extra_header),
243236
None => {
244237
*state = State::Message;
245-
return Self::next_inner_(i, state);
238+
Self::next_inner_(input, state)?
246239
}
247240
}
248241
}
249242
Message => {
250-
let message = terminated(decode::message, eof).parse_next(&mut i)?;
243+
let message = terminated(decode::message, eof).parse_next(input)?;
251244
debug_assert!(
252-
i.is_empty(),
245+
input.is_empty(),
253246
"we should have consumed all data - otherwise iter may go forever"
254247
);
255-
return Ok((i, Token::Message(message)));
248+
Token::Message(message)
256249
}
257250
})
258251
}

gix-object/src/tag/ref_iter.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,58 +59,57 @@ fn missing_field() -> crate::decode::Error {
5959

6060
impl<'a> TagRefIter<'a> {
6161
#[inline]
62-
fn next_inner(i: &'a [u8], state: &mut State) -> Result<(&'a [u8], Token<'a>), crate::decode::Error> {
63-
Self::next_inner_(i, state).map_err(crate::decode::Error::with_err)
62+
fn next_inner(mut i: &'a [u8], state: &mut State) -> Result<(&'a [u8], Token<'a>), crate::decode::Error> {
63+
let input = &mut i;
64+
let token = Self::next_inner_(input, state).map_err(crate::decode::Error::with_err)?;
65+
Ok((input, token))
6466
}
6567

6668
fn next_inner_(
67-
mut i: &'a [u8],
69+
input: &mut &'a [u8],
6870
state: &mut State,
69-
) -> Result<(&'a [u8], Token<'a>), winnow::error::ErrMode<crate::decode::ParseError>> {
71+
) -> Result<Token<'a>, winnow::error::ErrMode<crate::decode::ParseError>> {
7072
use State::*;
7173
Ok(match state {
7274
Target => {
7375
let target = (|i: &mut _| parse::header_field(i, b"object", parse::hex_hash))
7476
.context(StrContext::Expected("object <40 lowercase hex char>".into()))
75-
.parse_next(&mut i)?;
77+
.parse_next(input)?;
7678
*state = TargetKind;
77-
(
78-
i,
79-
Token::Target {
80-
id: ObjectId::from_hex(target).expect("parsing validation"),
81-
},
82-
)
79+
Token::Target {
80+
id: ObjectId::from_hex(target).expect("parsing validation"),
81+
}
8382
}
8483
TargetKind => {
8584
let kind = (|i: &mut _| parse::header_field(i, b"type", take_while(1.., AsChar::is_alpha)))
8685
.context(StrContext::Expected("type <object kind>".into()))
87-
.parse_next(&mut i)?;
86+
.parse_next(input)?;
8887
let kind = Kind::from_bytes(kind)
89-
.map_err(|_| winnow::error::ErrMode::from_error_kind(&i, winnow::error::ErrorKind::Verify))?;
88+
.map_err(|_| winnow::error::ErrMode::from_error_kind(input, winnow::error::ErrorKind::Verify))?;
9089
*state = Name;
91-
(i, Token::TargetKind(kind))
90+
Token::TargetKind(kind)
9291
}
9392
Name => {
9493
let tag_version = (|i: &mut _| parse::header_field(i, b"tag", take_while(1.., |b| b != NL[0])))
9594
.context(StrContext::Expected("tag <version>".into()))
96-
.parse_next(&mut i)?;
95+
.parse_next(input)?;
9796
*state = Tagger;
98-
(i, Token::Name(tag_version.as_bstr()))
97+
Token::Name(tag_version.as_bstr())
9998
}
10099
Tagger => {
101100
let signature = opt(|i: &mut _| parse::header_field(i, b"tagger", parse::signature))
102101
.context(StrContext::Expected("tagger <signature>".into()))
103-
.parse_next(&mut i)?;
102+
.parse_next(input)?;
104103
*state = Message;
105-
(i, Token::Tagger(signature))
104+
Token::Tagger(signature)
106105
}
107106
Message => {
108-
let (message, pgp_signature) = terminated(decode::message, eof).parse_next(&mut i)?;
107+
let (message, pgp_signature) = terminated(decode::message, eof).parse_next(input)?;
109108
debug_assert!(
110-
i.is_empty(),
109+
input.is_empty(),
111110
"we should have consumed all data - otherwise iter may go forever"
112111
);
113-
return Ok((i, Token::Body { message, pgp_signature }));
112+
Token::Body { message, pgp_signature }
114113
}
115114
})
116115
}

0 commit comments

Comments
 (0)