This is, for some reason, a huge pessimization. `rustc` fails to
optimize it as well as it did when it was part of `Scanner`.
This is however kinda needed if I want to avoid having this code
duplicated in every implementation of the input.
The refactoring added `next_is` which takes a `&str` as parameter, while
we only use it with strings of lengths 2 and 3. Replacing this by 2
dedicated methods (which can be added to the trait interface and only
specialized if needed) removes almost all the overhead that was added by
`Input`.
Hiding character fetching behind this interface allows us to create more
specific implementations when is appropriate. For instance, an instance
of `Input` can be created for a `&str`, allowing for borrowing and more
efficient peeking and traversing than if we were to fetch characters one
at a time and placing them into a temporary buffer.
These are corner cases not tested by the `yaml-test-suite`.
Parsing for the reported input has been fixed, as well as other
similar-looking inputs which make use of nested implicit flow mappings
and implicit null keys and values.
Fixes#1.
Internally, `ScanError` stores a `String`. Having `new` take a `&str`
misleadingly indicates that it stores a `&str`. This commit changes
`new` so that it takes a `String`, and adds a convenience method,
`new_str` that takes a `&str` and allocates a `String` for it.
This removes all allocations in the `Scanner` code. The downside is that
the buffer is now stored in the `Scanner` structure, making it 48 bytes
larger. This however makes the code much more performant.
`self.buffer` is a `VecDeque<char>`, meaning that characters are stored
on 4B. When reading as we used to do, this means that every 1 byte
character we read was turned into 4 bytes, which was turned into 1 byte
in `String::extend`.
Instead of going through `self.buffer`, use a local `String` to store
the characters before pushing them to `string`.
Instead of doing a loop that goes:
* fetch from input stream
* push char into string
Make a loop that fetches characters while they're not a breakz and
_then_ extend the string. This avoids a bunch of reallocations.
If building release mode, remove debug code. Now, the `debug_print!`
macro resolves to nothing in release build.
In debug build, don't check the environment for each print. This has a
huge overhead. The environment is only checked once and next checks are
made against a simple boolean value.
This is a huge commit that cannot easily be broken down as it contains
fixes for the next ignored test in the suite which, one fixed, broke
tests that used to pass and were only then fixed.
There is also a substantial amount of comments that were added,
especially around `SimpleKey`. Minor improvements around the code were
added and I did not bother making a separate commit for them.
Overall, that commit fixes 7 tests from the matrix that were related to
the handling of simple keys.