That way it's possible to continue parsing past the quoted string.
Showing the changes to git-quote/src (1 of 2 files). Show all
Unified · Split
| @@ -28,23 +28,25 @@ use std::{borrow::Cow, io::Read}; · 27 unmodified lines | |||
| 28 | 28 | ||
| 29 | use bstr::{BStr, BString, ByteSlice}; | 29 | use bstr::{BStr, BString, ByteSlice}; |
| 30 | 30 | ||
| 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. |
| 32 | /// | 32 | /// |
| 33 | /// The `input` is returned unaltered if it doesn't start with a `"` character to indicate | 33 | /// 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 | ||
| 35 | /// | 36 | /// |
| 36 | /// See [the tests][tests] for quotation examples. | 37 | /// See [the tests][tests] for quotation examples. |
| 37 | /// | 38 | /// |
| 38 | /// [tests]: https://github.com/Byron/gitoxide/blob/e355b4ad133075152312816816af5ce72cf79cff/git-odb/src/alternate/unquote.rs#L110-L118 | 39 | /// [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> { |
| 40 | if !input.starts_with(b"\"") { | 41 | if !input.starts_with(b"\"") { |
| 41 | return Ok(input.into()); | 42 | return Ok((input.into(), input.len())); |
| 42 | } | 43 | } |
| 43 | if input.len() < 2 { | 44 | if input.len() < 2 { |
| 44 | return Err(undo::Error::new("Input must be surrounded by double quotes", input)); | 45 | return Err(undo::Error::new("Input must be surrounded by double quotes", input)); |
| 45 | } | 46 | } |
| 46 | let original = input.as_bstr(); | 47 | let original = input.as_bstr(); |
| 47 | let mut input = &input[1..]; | 48 | let mut input = &input[1..]; |
| 49 | let mut consumed = 1; | ||
| 48 | let mut out = BString::default(); | 50 | let mut out = BString::default(); |
| 49 | fn consume_one_past(input: &mut &BStr, position: usize) -> Result<u8, undo::Error> { | 51 | fn consume_one_past(input: &mut &BStr, position: usize) -> Result<u8, undo::Error> { |
| 50 | *input = input | 52 | *input = input |
| @@ -59,10 +61,12 @@ pub fn undo(input: &BStr) -> Result<Cow<'_, BStr>, undo::Error> { · 8 unmodified lines | |||
| 59 | match input.find_byteset(b"\"\\") { | 61 | match input.find_byteset(b"\"\\") { |
| 60 | Some(position) => { | 62 | Some(position) => { |
| 61 | out.extend_from_slice(&input[..position]); | 63 | out.extend_from_slice(&input[..position]); |
| 64 | consumed += position + 1; | ||
| 62 | match input[position] { | 65 | match input[position] { |
| 63 | b'"' => break, | 66 | b'"' => break, |
| 64 | b'\\' => { | 67 | b'\\' => { |
| 65 | let next = consume_one_past(&mut input, position)?; | 68 | let next = consume_one_past(&mut input, position)?; |
| 69 | consumed += 1; | ||
| 66 | match next { | 70 | match next { |
| 67 | b'n' => out.push(b'\n'), | 71 | b'n' => out.push(b'\n'), |
| 68 | b'r' => out.push(b'\r'), | 72 | b'r' => out.push(b'\r'), |
| @@ -88,6 +92,7 @@ pub fn undo(input: &BStr) -> Result<Cow<'_, BStr>, undo::Error> { · 19 unmodified lines | |||
| 88 | let byte = btoi::btou_radix(&buf, 8).map_err(|e| undo::Error::new(e, original))?; | 92 | let byte = btoi::btou_radix(&buf, 8).map_err(|e| undo::Error::new(e, original))?; |
| 89 | out.push(byte); | 93 | out.push(byte); |
| 90 | input = &input[2..]; | 94 | input = &input[2..]; |
| 95 | consumed += 2; | ||
| 91 | } | 96 | } |
| 92 | _ => { | 97 | _ => { |
| 93 | return Err(undo::Error::UnsupportedEscapeByte { | 98 | return Err(undo::Error::UnsupportedEscapeByte { |
| @@ -102,9 +107,10 @@ pub fn undo(input: &BStr) -> Result<Cow<'_, BStr>, undo::Error> { · 8 unmodified lines | |||
| 102 | } | 107 | } |
| 103 | None => { | 108 | None => { |
| 104 | out.extend_from_slice(input); | 109 | out.extend_from_slice(input); |
| 110 | consumed += input.len(); | ||
| 105 | break; | 111 | break; |
| 106 | } | 112 | } |
| 107 | } | 113 | } |
| 108 | } | 114 | } |
| 109 | Ok(out.into()) | 115 | Ok((out.into(), consumed)) |
| 110 | } | 116 | } |