History

feat!: `ansi_c::unquote()` returns the amount of consumed bytes. (#301)

That way it's possible to continue parsing past the quoted string.

Sebastian Thiel committed 4 years ago

Commit a052d791 parent 22c776b2 files · +30 −19Browse files

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

Unified · Split

git-quote/src/ansi_c.rs+11−5
@@ -28,23 +28,25 @@ use std::{borrow::Cow, io::Read}; · 27 unmodified lines
2828
2929 use bstr::{BStr, BString, ByteSlice};
3030
31−/// Unquote the given ansi-c quoted `input` string.
31+/// Unquote the given ansi-c quoted `input` string, returning it and all of the consumed bytes.
3232 ///
3333 /// The `input` is returned unaltered if it doesn't start with a `"` character to indicate
34−/// quotation, otherwise a new unqoted string will always be allocated.
34+/// quotation, otherwise a new unquoted string will always be allocated.
35+/// The amount of consumed bytes allow to pass strings that start with a quote, and skip all quoted text for additional processing
3536 ///
3637 /// See [the tests][tests] for quotation examples.
3738 ///
3839 /// [tests]: https://github.com/Byron/gitoxide/blob/e355b4ad133075152312816816af5ce72cf79cff/git-odb/src/alternate/unquote.rs#L110-L118
39−pub fn undo(input: &BStr) -> Result<Cow<'_, BStr>, undo::Error> {
40+pub fn undo(input: &BStr) -> Result<(Cow<'_, BStr>, usize), undo::Error> {
4041 if !input.starts_with(b"\"") {
41− return Ok(input.into());
42+ return Ok((input.into(), input.len()));
4243 }
4344 if input.len() < 2 {
4445 return Err(undo::Error::new("Input must be surrounded by double quotes", input));
4546 }
4647 let original = input.as_bstr();
4748 let mut input = &input[1..];
49+ let mut consumed = 1;
4850 let mut out = BString::default();
4951 fn consume_one_past(input: &mut &BStr, position: usize) -> Result<u8, undo::Error> {
5052 *input = input
@@ -59,10 +61,12 @@ pub fn undo(input: &BStr) -> Result<Cow<'_, BStr>, undo::Error> { · 8 unmodified lines
5961 match input.find_byteset(b"\"\\") {
6062 Some(position) => {
6163 out.extend_from_slice(&input[..position]);
64+ consumed += position + 1;
6265 match input[position] {
6366 b'"' => break,
6467 b'\\' => {
6568 let next = consume_one_past(&mut input, position)?;
69+ consumed += 1;
6670 match next {
6771 b'n' => out.push(b'\n'),
6872 b'r' => out.push(b'\r'),
@@ -88,6 +92,7 @@ pub fn undo(input: &BStr) -> Result<Cow<'_, BStr>, undo::Error> { · 19 unmodified lines
8892 let byte = btoi::btou_radix(&buf, 8).map_err(|e| undo::Error::new(e, original))?;
8993 out.push(byte);
9094 input = &input[2..];
95+ consumed += 2;
9196 }
9297 _ => {
9398 return Err(undo::Error::UnsupportedEscapeByte {
@@ -102,9 +107,10 @@ pub fn undo(input: &BStr) -> Result<Cow<'_, BStr>, undo::Error> { · 8 unmodified lines
102107 }
103108 None => {
104109 out.extend_from_slice(input);
110+ consumed += input.len();
105111 break;
106112 }
107113 }
108114 }
109− Ok(out.into())
115+ Ok((out.into(), consumed))
110116 }