Skip to content

Commit 46e9545

Browse files
move codePointAt0 from JS to purs
1 parent 2c2418a commit 46e9545

File tree

2 files changed

+72
-44
lines changed

2 files changed

+72
-44
lines changed

src/Data/String/CodePoints.js

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,40 @@ var hasStringIterator =
1010
var hasFromCodePoint = typeof String.prototype.fromCodePoint === "function";
1111
var hasCodePointAt = typeof String.prototype.codePointAt === "function";
1212

13-
var codePointAt0 = hasCodePointAt
14-
? function (str) { return str.codePointAt(0); }
15-
: function (str) {
16-
if (str.length === 1) {
17-
return str.charCodeAt(0);
18-
}
19-
return ((str.charCodeAt(0) - 0xD800) * 0x400 + (str.charCodeAt(1) - 0xDC00) + 0x10000);
13+
exports._unsafeCharCodeAt = function (i) {
14+
return function (str) {
15+
return str.charCodeAt(i);
2016
};
17+
};
18+
19+
exports._unsafeCodePointAt0 = function (fallback) {
20+
return hasCodePointAt
21+
? function (str) { return str.codePointAt(0); }
22+
: fallback;
23+
};
2124

2225
exports._codePointAt = function (fallback) {
2326
return function (Just) {
2427
return function (Nothing) {
25-
return function (index) {
26-
return function (str) {
27-
var length = str.length;
28-
if (index < 0 || index >= length) return Nothing;
29-
if (hasArrayFrom) {
30-
var cps = Array.from(str);
31-
if (index >= cps.length) return Nothing;
32-
return Just(codePointAt0(cps[index]));
33-
} else if (hasStringIterator) {
34-
var iter = str[Symbol.iterator]();
35-
for (var i = index;; --i) {
36-
var o = iter.next();
37-
if (o.done) return Nothing;
38-
if (i === 0) return Just(codePointAt0(o.value));
28+
return function (unsafeCodePointAt0) {
29+
return function (index) {
30+
return function (str) {
31+
var length = str.length;
32+
if (index < 0 || index >= length) return Nothing;
33+
if (hasArrayFrom) {
34+
var cps = Array.from(str);
35+
if (index >= cps.length) return Nothing;
36+
return Just(unsafeCodePointAt0(cps[index]));
37+
} else if (hasStringIterator) {
38+
var iter = str[Symbol.iterator]();
39+
for (var i = index;; --i) {
40+
var o = iter.next();
41+
if (o.done) return Nothing;
42+
if (i === 0) return Just(unsafeCodePointAt0(o.value));
43+
}
3944
}
40-
}
41-
return fallback(index)(str);
45+
return fallback(index)(str);
46+
};
4247
};
4348
};
4449
};
@@ -105,20 +110,22 @@ exports._take = function (fallback) {
105110
};
106111

107112
exports._toCodePointArray = function (fallback) {
108-
if (hasArrayFrom) {
109-
return function (str) {
110-
return Array.from(str, codePointAt0);
111-
};
112-
} else if (hasStringIterator) {
113-
return function (str) {
114-
var accum = [];
115-
var iter = str[Symbol.iterator]();
116-
for (;;) {
117-
var o = iter.next();
118-
if (o.done) return accum;
119-
accum.push(codePointAt0(o.value));
120-
}
121-
};
122-
}
123-
return fallback;
113+
return function (unsafeCodePointAt0) {
114+
if (hasArrayFrom) {
115+
return function (str) {
116+
return Array.from(str, unsafeCodePointAt0);
117+
};
118+
} else if (hasStringIterator) {
119+
return function (str) {
120+
var accum = [];
121+
var iter = str[Symbol.iterator]();
122+
for (;;) {
123+
var o = iter.next();
124+
if (o.done) return accum;
125+
accum.push(unsafeCodePointAt0(o.value));
126+
}
127+
};
128+
}
129+
return fallback;
130+
};
124131
};

src/Data/String/CodePoints.purs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import Data.String as String
3131
import Data.String (Pattern(..), Replacement(..), charAt, charCodeAt, contains, fromCharArray, joinWith, localeCompare, null, replace, replaceAll, split, stripPrefix, stripSuffix, toChar, toCharArray, toLower, toUpper, trim) as StringReExports
3232
import Data.Tuple (Tuple(Tuple))
3333
import Data.Unfoldable (unfoldr)
34-
import Prelude (class Eq, class Ord, (&&), (||), (*), (+), (-), (<$>), (<), (<=), (<<<), (/), (<>), mod)
34+
import Prelude (class Eq, class Ord, (&&), (||), (*), (+), (-), (<$>), (<), (<=), (<<<), (/), (<>), (==), mod)
3535

3636

3737
newtype CodePoint = CodePoint Int
@@ -48,8 +48,8 @@ codePointToInt :: CodePoint -> Int
4848
codePointToInt (CodePoint n) = n
4949

5050
codePointFromSurrogatePair :: Int -> Int -> Maybe CodePoint
51-
codePointFromSurrogatePair lead trail | isLead lead && isTrail trail
52-
= Just (unsurrogate lead trail)
51+
codePointFromSurrogatePair lead trail | isLead lead && isTrail trail =
52+
Just (unsurrogate lead trail)
5353
codePointFromSurrogatePair _ _ = Nothing
5454

5555
unsurrogate :: Int -> Int -> CodePoint
@@ -64,14 +64,34 @@ isTrail cu = 0xDC00 <= cu && cu <= 0xDFFF
6464
fromCharCode :: Int -> String
6565
fromCharCode = String.singleton <<< Char.fromCharCode
6666

67+
unsafeCodePointAt0 :: String -> CodePoint
68+
unsafeCodePointAt0 = _unsafeCodePointAt0 unsafeCodePointAt0Fallback
69+
70+
foreign import _unsafeCodePointAt0
71+
:: (String -> CodePoint)
72+
-> String
73+
-> CodePoint
74+
75+
unsafeCodePointAt0Fallback :: String -> CodePoint
76+
unsafeCodePointAt0Fallback s | String.length s == 1 = CodePoint (_unsafeCharCodeAt 0 s)
77+
unsafeCodePointAt0Fallback s = CodePoint (((lead - 0xD800) * 0x400) + (trail - 0xDC00) + 0x10000)
78+
where
79+
lead = _unsafeCharCodeAt 0 s
80+
trail = _unsafeCharCodeAt 1 s
81+
82+
foreign import _unsafeCharCodeAt :: Int -> String -> Int
83+
6784

6885
codePointAt :: Int -> String -> Maybe CodePoint
69-
codePointAt = _codePointAt codePointAtFallback Just Nothing
86+
codePointAt 0 "" = Nothing
87+
codePointAt 0 s = Just (unsafeCodePointAt0 s)
88+
codePointAt n s = _codePointAt codePointAtFallback Just Nothing unsafeCodePointAt0 n s
7089

7190
foreign import _codePointAt
7291
:: (Int -> String -> Maybe CodePoint)
7392
-> (forall a. a -> Maybe a)
7493
-> (forall a. Maybe a)
94+
-> (String -> CodePoint)
7595
-> Int
7696
-> String
7797
-> Maybe CodePoint
@@ -174,10 +194,11 @@ takeWhile p s = take (count p s) s
174194

175195

176196
toCodePointArray :: String -> Array CodePoint
177-
toCodePointArray = _toCodePointArray toCodePointArrayFallback
197+
toCodePointArray = _toCodePointArray toCodePointArrayFallback unsafeCodePointAt0
178198

179199
foreign import _toCodePointArray
180200
:: (String -> Array CodePoint)
201+
-> (String -> CodePoint)
181202
-> String
182203
-> Array CodePoint
183204

0 commit comments

Comments
 (0)