Skip to content

0.8.0

Compare
Choose a tag to compare
@stephencelis stephencelis released this 10 Mar 18:53
· 84 commits to main since this release
  • Added: A case-iterable, raw-representable parser. Simply tack .parser() onto any conforming type:

    enum Role: String, CaseIterable {
      case admin
      case guest
      case member
    }
    
    try Role.parser().parse("admin") // Role.admin
  • Fixed: An Xcode 13.3 compiler error has been fixed.

  • Fixed: Optionally will now backtrack if the parser fails (thanks @randomeizer).

  • Fixed: Double.parser() now parses as freely as Double.init's LosslessStringConvertible functionality.

  • Optimized: Peek and Not will only backtrack when they are successful (i.e., if Peek's upstream parser successfully parses a value, or if Not's upstream parser fails to parse a value). Backtracking on failure is now delegated to any upstream OneOfs.

  • Optimized: OneOfMany no longer backtracks its final failure, bringing it in line with the behavior of the variadic OneOfs.

  • Breaking change: The non-inout overloads of Parser.parse now attempt to fully consume Collection-based inputs.

    // Before:
    try Int.parser().parse("42hello") // 42
    
    // After:
    try Int.parser().parse("42hello")
    // error: unexpected input
    //  --> input:1:13
    // 1 | 42hello
    //   |   ^ expected end of input

    This change makes parsing a bit more strict by default in order to catch potential issues with input.

    If you want to ignore trailing output, use the inout version of parse, or explicitly describe how the input should be ignored in the parser, for example using Optionally { Rest() }.map { _ in () }.

  • Breaking change: The Rest parser now fails when the rest of input is empty.

    // Before:
    try Rest().parse("") // ""
    
    // After:
    try Rest().parse("")
    /// error: unexpected input
    ///  --> input:1:1
    /// 1 |
    ///   | ^ expected a non-empty input

    If your use of Rest should not fail on empty input, wrap it explicitly in an Optionally parser, or use replaceError(with:) to provide a default value of "".

  • Breaking change: Peek is now a Void parser. It can be used to inspect a value in order to test that a parser should be successful, but capturing any data is now the responsible for the parsers that comes afterward (thanks @randomeizer).

  • Breaking change: The isSigned parameter of Int.parser() has been removed. Int.parser() will now always parse a sign if FixedWidthInteger.isSigned returns true (e.g., Int.parser() will parse a sign, UInt.parser() will not.).

    If you want to parse a number without a sign, use a more explicit parser, or test for the sign before using Int.parser(). E.g.:

    let digits = Prefix { $0.isNumber }.compactMap(Int.init)
    // ...or...
    let digits = Parse {
      Not { OneOf { "-"; "+" } }
      Int.parser()
    }
  • Updated: Double.parser() can now be used on any type that conforms to BinaryFloatingPoint, including Float16.

  • Updated: Many's updateAccumulatingResult can now throw.

  • Updated: Documentation has been revamped, including a new DocC-based static site with articles that cover common topics.

  • Infrastructure: Documentation fixes (thanks @haikusw).