ecluse:ecluse-core
Safe HaskellNone
LanguageGHC2021

Ecluse.Core.Version.Token

Description

Low-level lexical atoms shared by the per-ecosystem version grammars.

A VToken is a single numeric or textual run, with the ordering rule common to the RubyGems and PEP 440-local grammars: numeric tokens outrank textual ones, numerics compare numerically, text compares lexically. (The semver prerelease rule is the opposite -- numeric identifiers rank below alphanumeric ones -- so it lives with the semver grammar, not here.)

The two segment readers, parseNumSeg (validating) and numOr0 (total over already-validated input), are used by more than one grammar. Everything here is purely lexical: no ecosystem ordering policy lives in this module.

Synopsis

Documentation

data VToken Source #

A version token: a numeric run or a textual run. Its Ord is the RubyGems / PEP 440-local rule -- numeric tokens outrank textual ones, numerics compare numerically, text compares lexically. (Semver prerelease ordering is the opposite and is handled in Ecluse.Core.Version.Semver.)

Constructors

VNum Integer 
VStr Text 

Instances

Instances details
Show VToken Source # 
Instance details

Defined in Ecluse.Core.Version.Token

Eq VToken Source # 
Instance details

Defined in Ecluse.Core.Version.Token

Methods

(==) :: VToken -> VToken -> Bool #

(/=) :: VToken -> VToken -> Bool #

Ord VToken Source # 
Instance details

Defined in Ecluse.Core.Version.Token

parseNumSeg :: Text -> Maybe Integer Source #

Parse a non-empty, all-digit segment as an integer.

numOr0 :: Text -> Integer Source #

Read an all-digit (already validated) run as an integer, defaulting to 0.

isAsciiAlphaNum :: Char -> Bool Source #

ASCII-only "alphanumeric" predicate: an ASCII letter or ASCII digit. Use this -- not isAlphaNum, which is Unicode-aware -- wherever the PEP 440 and Gem::Version grammars gate "alphanumeric" characters: Python's packaging and Ruby's Gem::Version are ASCII-only, so a Unicode-aware gate both over-accepts (fullwidth/Arabic-Indic digits, 1.0+café) and mis-orders (a Unicode "digit" that is not an ASCII digit gets classified as text). isDigit is already ASCII-only, so it is reused directly.

maxVersionLength :: Int Source #

The maximum length of a version string the hand-rolled numeric grammars (Ecluse.Core.Version.Pep440 and Ecluse.Core.Version.Gem) will parse. It bounds the cost of reading numeric segments: a segment is turned into an Integer with readMaybe, which is quadratic in the digit count, so an unbounded digit run in hostile registry metadata would be an algorithmic-complexity DoS. Real version strings are tiny -- npm caps its own version field at 256 characters -- so this far larger bound rejects only adversarial input. A version past it fails to parse and is served raw without an ordering key (the total-by-design mkVersion path in Ecluse.Core.Version: a version is never dropped over a parser gap).