Skip to content

Commit

Permalink
feat(char): Change char api and behaviour
Browse files Browse the repository at this point in the history
Choosing a specific range of chars is now possible using `char.inRanges()` rather than a `ranges` option.

The likelihood of obtaining a given character should now be roughly the same as any other character, at least to the same extent as performing modulo-based lookup on a array of characters
  • Loading branch information
justinvdm committed May 16, 2020
1 parent 6a1027d commit f2e15c5
Show file tree
Hide file tree
Showing 7 changed files with 397 additions and 101 deletions.
85 changes: 57 additions & 28 deletions char.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,76 @@
var hash = require('./hash')
var conj = require('./utils/conj')
var defaults = require('./utils/defaults')
var fit = require('./utils/fit')
var fitRanges = require('./utils/fitRanges')
var fromCodePoint = require('./utils/fromCodePoint')

var DEFAULT_RANGES = [
// ascii lower
var char = charInRanges([
// ascii
[0x61, 0x7a],

// ascii upper
[0x41, 0x5a],
// latin1
[0x0020, 0x007e],
[0x00a0, 0x00ff]
])

// latin-1 supplement lower
[0xdf, 0xf6],
[0xf8, 0xff],
char.inRanges = charInRanges

// latin-1 supplement upper
char.unicode = char
char.ascii = charInRanges([[0x61, 0x7a]])
char.latin1 = charInRanges([
[0x0020, 0x007e],
[0x00a0, 0x00ff]
])
char.asciiLower = charInRanges([[0x61, 0x7a]])
char.asciiUpper = charInRanges([[0x41, 0x5a]])
char.digit = charInRanges([[0x30, 0x39]])
char.latin1Upper = charInRanges([
[0xdf, 0xf6],
[0xf8, 0xff]
])
char.latin1Lower = charInRanges([
[0xc0, 0xd6],
[0xd8, 0xde],
[0xd8, 0xde]
])

// digits
[0x30, 0x39]
]
char.asciiLetter = charInRanges([char.asciiLower, char.asciiUpper])
char.latin1Letter = charInRanges([char.latin1Lower, char.latin1Upper])
char.alphanumeric = charInRanges([char.asciiLetter, char.digit])
char.lower = charInRanges([char.asciiLower, char.latin1Lower])
char.upper = charInRanges([char.latin1Upper, char.latin1Upper])
char.letter = charInRanges([char.asciiLetter, char.latin1Letter])

function char(input, opts) {
opts = opts || 0
var ranges = defaults(opts.ranges, DEFAULT_RANGES)
function charInRanges(ranges) {
ranges = normalizeRanges(ranges)
var fitFn = fitRanges(ranges)

var id = hash([input, 'char'])
var range = ranges[id % ranges.length]
charFn.__fictional_char = {
ranges: ranges
}

return charFn

id = hash(id)
return fromCodePoint(fit(id, range[0], range[1]))
function charFn(input) {
return fromCodePoint(fitFn(hash([input, 'char'])))
}
}

char.options = function charOptions(opts) {
var base = this
charFn.options = char.options
return charFn
function normalizeRanges(ranges) {
ranges = [].concat(ranges)
var results = []
var i = -1
var n = ranges.length
var range

function charFn(input, overrides) {
return base(input, conj(opts, overrides))
while (++i < n) {
range = ranges[i]

if (range.__fictional_char) {
results.push.apply(results, range.__fictional_char.ranges)
} else {
results.push(range)
}
}

return results
}

module.exports = char
28 changes: 23 additions & 5 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,31 @@ declare const dateString: DateString

export { dateString }

export interface CharOptions {
ranges: [number, number][]
export interface CharFn {
__fictional_char: unknown
(input: Input): string
}

export interface Char {
(input: Input, options?: Partial<CharOptions>): string
options(overrides?: Partial<CharOptions>): this
export type CharRange = [number, number] | CharFn

export interface Char extends CharFn {
inRanges(ranges: CharRange[]): Char

ascii: CharFn
latin1: CharFn

digit: CharFn
asciiLower: CharFn
asciiUpper: CharFn
latin1Upper: CharFn
latin1Lower: CharFn

asciiLetter: CharFn
latin1Letter: CharFn
alphanumeric: CharFn
lower: CharFn
upper: CharFn
letter: CharFn
}

declare const char: Char
Expand Down

0 comments on commit f2e15c5

Please sign in to comment.