commit aa2867a7159d7193898b844ebe6b16a6cf35ea32
parent d9ab0c6d127898112f188f0bb5e9b3c3a29c7ccb
Author: Jared Tobin <jared@jtobin.io>
Date: Tue, 12 Mar 2019 20:56:28 +1300
Add various vatp-casting functions.
Diffstat:
M | src/internal/co.js | | | 147 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
M | test/co.test.js | | | 39 | ++++++++++++++++++++++++++++++++++++++- |
2 files changed, 184 insertions(+), 2 deletions(-)
diff --git a/src/internal/co.js b/src/internal/co.js
@@ -126,6 +126,15 @@ const hex2patp = (hex) =>
patp(new BN(hex, 'hex'))
/**
+ * Convert a hex-encoded string to a @p-encoded string.
+ *
+ * @param {String} hex
+ * @return {String}
+ */
+const hex2vatp = (hex) =>
+ vatp(new BN(hex, 'hex'))
+
+/**
* Convert a Buffer to a @p-encoded string.
*
* @param {Buffer} buf
@@ -135,6 +144,15 @@ const buf2patp = (buf) =>
hex2patp(buf.toString('hex'))
/**
+ * Convert a Buffer to a @p-encoded string.
+ *
+ * @param {Buffer} buf
+ * @return {String}
+ */
+const buf2vatp = (buf) =>
+ hex2vatp(buf.toString('hex'))
+
+/**
* Convert a @p-encoded string to a hex-encoded string.
*
* @param {String} name @p
@@ -163,6 +181,34 @@ const patp2hex = (name) => {
}
/**
+ * Convert a @p-encoded string to a hex-encoded string.
+ *
+ * @param {String} name @p
+ * @return {String}
+ */
+const vatp2hex = (name) => {
+ if (isValidPat(name) === false) {
+ throw new Error('patp2hex: not a valid @p')
+ }
+ const syls = patp2syls(name)
+
+ const syl2bin = idx =>
+ idx.toString(2).padStart(8, '0')
+
+ const addr = lodash.reduce(syls, (acc, syl, idx) =>
+ idx % 2 !== 0 || syls.length === 1
+ ? acc + syl2bin(suffixes.indexOf(syl))
+ : acc + syl2bin(prefixes.indexOf(syl)),
+ '')
+
+ const bn = new BN(addr, 2)
+ const hex = ob.fynd(bn).toString('hex')
+ return hex.length % 2 !== 0
+ ? hex.padStart(hex.length + 1, '0')
+ : hex
+}
+
+/**
* Convert a @p-encoded string to a Buffer.
*
* @param {String} name
@@ -172,6 +218,15 @@ const patp2buf = name =>
Buffer.from(patp2hex(name), 'hex')
/**
+ * Convert a @p-encoded string to a Buffer.
+ *
+ * @param {String} name
+ * @return {Buffer}
+ */
+const vatp2buf = name =>
+ Buffer.from(vatp2hex(name), 'hex')
+
+/**
* Convert a @p-encoded string to a bignum.
*
* @param {String} name @p
@@ -181,6 +236,15 @@ const patp2bn = name =>
new BN(patp2hex(name), 'hex')
/**
+ * Convert a @p-encoded string to a bignum.
+ *
+ * @param {String} name @p
+ * @return {BN}
+ */
+const vatp2bn = name =>
+ new BN(vatp2hex(name), 'hex')
+
+/**
* Convert a @p-encoded string to a decimal-encoded string.
*
* @param {String} name @p
@@ -197,6 +261,22 @@ const patp2dec = name => {
}
/**
+ * Convert a @p-encoded string to a decimal-encoded string.
+ *
+ * @param {String} name @p
+ * @return {String}
+ */
+const vatp2dec = name => {
+ let bn
+ try {
+ bn = vatp2bn(name)
+ } catch(_) {
+ throw new Error('patp2dec: not a valid @p')
+ }
+ return bn.toString()
+}
+
+/**
* Convert a number to a @q-encoded string.
*
* @param {String, Number, BN} arg
@@ -349,6 +429,32 @@ const clan = who => {
}
/**
+ * Determine the ship class of a @p value.
+ *
+ * @param {String} @p
+ * @return {String}
+ */
+const clen = who => {
+ let name
+ try {
+ name = vatp2bn(who)
+ } catch(_) {
+ throw new Error('clan: not a valid @p')
+ }
+
+ const wid = met(three, name)
+ return wid.lte(one)
+ ? 'galaxy'
+ : wid.eq(two)
+ ? 'star'
+ : wid.lte(four)
+ ? 'planet'
+ : wid.lte(new BN(8))
+ ? 'moon'
+ : 'comet'
+}
+
+/**
* Determine the parent of a @p value.
*
* @param {String} @p
@@ -383,6 +489,40 @@ const sein = name => {
}
/**
+ * Determine the parent of a @p value.
+ *
+ * @param {String} @p
+ * @return {String}
+ */
+const sign = name => {
+ let who
+ try {
+ who = vatp2bn(name)
+ } catch(_) {
+ throw new Error('sein: not a valid @p')
+ }
+
+ let mir
+ try {
+ mir = clen(name)
+ } catch(_) {
+ throw new Error('sein: not a valid @p')
+ }
+
+ const res =
+ mir === 'galaxy'
+ ? who
+ : mir === 'star'
+ ? end(three, one, who)
+ : mir === 'planet'
+ ? end(four, one, who)
+ : mir === 'moon'
+ ? end(five, one, who)
+ : zero
+ return vatp(res)
+}
+
+/**
* Weakly check if a string is a valid @p or @q value.
*
* This is, at present, a pretty weak sanity check. It doesn't confirm the
@@ -508,5 +648,10 @@ module.exports = {
isValidPatq: isValidPat, // reserving for diff impls in future
isValidPatp: isValidPat,
- vatp
+ vatp,
+ vatp2hex,
+ hex2vatp,
+ vatp2dec,
+ sign,
+ clen
}
diff --git a/test/co.test.js b/test/co.test.js
@@ -6,12 +6,18 @@ const {
patp2hex,
hex2patp,
patp2dec,
+ vatp,
+ vatp2hex,
+ hex2vatp,
+ vatp2dec,
patq,
patq2hex,
hex2patq,
patq2dec,
clan,
sein,
+ clen,
+ sign,
eqPatq,
isValidPatq,
isValidPatp
@@ -22,12 +28,17 @@ const patps = jsc.uint32.smap(
pp => parseInt(patp2dec(pp))
)
+const vatps = jsc.uint32.smap(
+ num => vatp(num),
+ pp => parseInt(vatp2dec(pp))
+)
+
const patqs = jsc.uint32.smap(
num => patq(num),
pq => parseInt(patq2dec(pq))
)
-describe('patp, etc.', () => {
+describe('patp, vatp, etc.', () => {
it('patp2dec matches expected reference values', () => {
expect(patp2dec('~zod')).to.equal('0')
expect(patp2dec('~lex')).to.equal('200')
@@ -75,6 +86,19 @@ describe('patp, etc.', () => {
jsc.assert(iso1)
})
+ it('vatp and vatp2dec are inverses', () => {
+ let iso0 = jsc.forall(jsc.uint32, num =>
+ parseInt(vatp2dec(vatp(num))) === num
+ )
+
+ let iso1 = jsc.forall(vatps, vp =>
+ vatp(vatp2dec(vp)) === vp
+ )
+
+ jsc.assert(iso0, { tests: 10000 })
+ jsc.assert(iso1, { tests: 10000 })
+ })
+
it('patp2hex and hex2patp are inverses', () => {
let iso0 = jsc.forall(jsc.uint32, num =>
parseInt(patp2hex(hex2patp(num.toString(16))), 16) === num
@@ -87,6 +111,19 @@ describe('patp, etc.', () => {
jsc.assert(iso0)
jsc.assert(iso1)
})
+
+ it('vatp2hex and hex2vatp are inverses', () => {
+ let iso0 = jsc.forall(jsc.uint32, num =>
+ parseInt(vatp2hex(hex2vatp(num.toString(16))), 16) === num
+ )
+
+ let iso1 = jsc.forall(vatps, vp =>
+ hex2vatp(vatp2hex(vp)) === vp
+ )
+
+ jsc.assert(iso0)
+ jsc.assert(iso1)
+ })
})
describe('patq, etc.', () => {