From 1cbd2e725a911b1294914df9e9aa154233310dcb Mon Sep 17 00:00:00 2001 From: Leonora Tindall Date: Thu, 11 Nov 2021 12:52:47 -0600 Subject: [PATCH] Nora's solution to the challenge. Don't look at this before you've completed the challenge! This is not the only correct solution, just one example. I have notated the solution with comments beginning with NORA to help explain my reasoning and the purpose of each line. --- src/lib.rs | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6e4404c..3824336 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,8 @@ use std::io::Write; pub struct Parser { token: &'static [u8], suffix: &'static [u8], + /// NORA: Records the position in the token across calls to `process`. + pos: usize, } impl Parser { @@ -19,7 +21,11 @@ impl Parser { // // NOTE: This function signature should stay the same. pub fn new(token: &'static [u8], suffix: &'static [u8]) -> Self { - Self { token, suffix } + Self { + token, + suffix, + pos: 0, + } } /// Write the bytes given in `input` to `output`, plus the bytes in `suffix` @@ -56,7 +62,42 @@ impl Parser { // // NOTE: This function signature should stay the same. pub fn process(&mut self, input: &[u8], output: &mut dyn Write) -> Result<(), std::io::Error> { - output.write_all(input) + // NORA: Create a buffer to work in for just this call. + // We'll write the whole buffer at the end, unconditionally; + // the only question is what's in it. + let mut buffer = Vec::with_capacity(input.len() + self.suffix.len()); + + // NORA: Look at each byte in the input. + for byte in input { + // NORA: Unconditionally, write that byte into our buffer. + // No requirement calls for losing any bytes. + buffer.push(*byte); + + // NORA: Compare the current byte in the input to the current byte + // in the token. + if *byte == self.token[self.pos] { + // NORA: If this byte is a match, progress to the next token byte. + self.pos += 1; + // NORA: If we've reached the end of the token, + // that's a successful match. + if self.pos == self.token.len() { + // NORA: Write the whole suffix into the output buffer. + for suffix_byte in self.suffix { + buffer.push(*suffix_byte); + } + // NORA: And reset to zero, so we can look for a new match. + self.pos = 0; + } + } else { + // NORA: If the current input byte isn't a match for the current + // token byte, we have failed to match the token; + // reset to the beginning. + // This prevents e.g. "oat meal" from matching "oatmeal". + self.pos = 0; + } + } + + output.write_all(&buffer) } }