wao 0.27.0 → 0.27.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/encode.js +1452 -792
- package/cjs/toerl.js +173 -0
- package/esm/encode.js +1340 -510
- package/esm/toerl.js +162 -0
- package/package.json +1 -1
package/esm/toerl.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
export default function toErl(obj, indent = 0) {
|
|
2
|
+
const spaces = " ".repeat(indent)
|
|
3
|
+
|
|
4
|
+
// Handle null (as atom)
|
|
5
|
+
if (obj === null) {
|
|
6
|
+
return "null" // Erlang atom
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Handle undefined (as atom)
|
|
10
|
+
if (obj === undefined) {
|
|
11
|
+
return "undefined" // Erlang atom
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Handle boolean (as atom)
|
|
15
|
+
if (typeof obj === "boolean") {
|
|
16
|
+
return obj.toString() // true/false are atoms in Erlang
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Handle numbers
|
|
20
|
+
if (typeof obj === "number") {
|
|
21
|
+
if (Number.isInteger(obj)) {
|
|
22
|
+
return obj.toString()
|
|
23
|
+
} else {
|
|
24
|
+
// Format float properly
|
|
25
|
+
return obj.toString()
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Handle strings
|
|
30
|
+
if (typeof obj === "string") {
|
|
31
|
+
// Escape special characters
|
|
32
|
+
const escaped = obj
|
|
33
|
+
.replace(/\\/g, "\\\\")
|
|
34
|
+
.replace(/"/g, '\\"')
|
|
35
|
+
.replace(/\n/g, "\\n")
|
|
36
|
+
.replace(/\r/g, "\\r")
|
|
37
|
+
.replace(/\t/g, "\\t")
|
|
38
|
+
return `<<"${escaped}">>`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Handle symbols (as atom)
|
|
42
|
+
if (typeof obj === "symbol") {
|
|
43
|
+
const desc = obj.description || "Symbol.for()"
|
|
44
|
+
// Check if it's a simple atom or needs quoting
|
|
45
|
+
if (/^[a-z][a-zA-Z0-9_]*$/.test(desc)) {
|
|
46
|
+
return desc // Simple atom like: ok, error, undefined
|
|
47
|
+
} else {
|
|
48
|
+
return `'${desc}'` // Quoted atom for special cases
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Handle Buffer/Binary
|
|
53
|
+
if (
|
|
54
|
+
Buffer.isBuffer(obj) ||
|
|
55
|
+
(obj &&
|
|
56
|
+
typeof obj === "object" &&
|
|
57
|
+
obj.type === "Buffer" &&
|
|
58
|
+
Array.isArray(obj.data))
|
|
59
|
+
) {
|
|
60
|
+
const data = Buffer.isBuffer(obj) ? obj : Buffer.from(obj.data)
|
|
61
|
+
if (data.length === 0) {
|
|
62
|
+
return "<<>>"
|
|
63
|
+
}
|
|
64
|
+
const bytes = Array.from(data).join(",")
|
|
65
|
+
return `<<${bytes}>>`
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Handle Arrays
|
|
69
|
+
if (Array.isArray(obj)) {
|
|
70
|
+
if (obj.length === 0) {
|
|
71
|
+
return "[]"
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const items = obj.map(item => toErl(item, indent + 2))
|
|
75
|
+
|
|
76
|
+
// Check if it fits on one line
|
|
77
|
+
const oneLine = `[${items.join(", ")}]`
|
|
78
|
+
if (oneLine.length <= 80 && !items.some(item => item.includes("\n"))) {
|
|
79
|
+
return oneLine
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Multi-line format
|
|
83
|
+
const inner = items.map(item => `${spaces} ${item}`).join(",\n")
|
|
84
|
+
return `[\n${inner}\n${spaces}]`
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Handle Objects/Maps
|
|
88
|
+
if (typeof obj === "object" && obj !== null) {
|
|
89
|
+
const entries = Object.entries(obj)
|
|
90
|
+
|
|
91
|
+
if (entries.length === 0) {
|
|
92
|
+
return "#{}"
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const pairs = entries.map(([key, value]) => {
|
|
96
|
+
const erlangKey = `<<"${key}">>`
|
|
97
|
+
const erlangValue = toErl(value, indent + 2)
|
|
98
|
+
return `${erlangKey} => ${erlangValue}`
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
// Check if it fits on one line
|
|
102
|
+
const oneLine = `#{ ${pairs.join(", ")} }`
|
|
103
|
+
if (oneLine.length <= 80 && !pairs.some(pair => pair.includes("\n"))) {
|
|
104
|
+
return oneLine
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Multi-line format
|
|
108
|
+
const inner = pairs.map(pair => `${spaces} ${pair}`).join(",\n")
|
|
109
|
+
return `#{\n${inner}\n${spaces}}`
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Fallback
|
|
113
|
+
return "unknown"
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Helper function to convert JSON string or object
|
|
117
|
+
function convert(input) {
|
|
118
|
+
let obj
|
|
119
|
+
|
|
120
|
+
// If input is a string, try to parse it as JSON
|
|
121
|
+
if (typeof input === "string") {
|
|
122
|
+
try {
|
|
123
|
+
// First try to parse as JSON
|
|
124
|
+
obj = JSON.parse(input)
|
|
125
|
+
} catch (e) {
|
|
126
|
+
// If it fails, try to evaluate it (for cases with Symbol, Buffer, etc.)
|
|
127
|
+
try {
|
|
128
|
+
obj = eval(`(${input})`)
|
|
129
|
+
} catch (e2) {
|
|
130
|
+
throw new Error("Invalid input: not valid JSON or JavaScript object")
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
obj = input
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return toErl(obj)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Function to format test case for Erlang
|
|
141
|
+
function formatTestCase(obj, testName = "test") {
|
|
142
|
+
const erlangData = toErl(obj, 2)
|
|
143
|
+
|
|
144
|
+
// If it's a simple one-liner, put it inline
|
|
145
|
+
if (!erlangData.includes("\n") && erlangData.length < 60) {
|
|
146
|
+
return `${testName}_test() -> show(${erlangData}).`
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Multi-line format
|
|
150
|
+
return `${testName}_test() ->
|
|
151
|
+
show(${erlangData}).`
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Function to convert multiple test cases
|
|
155
|
+
function convertMultiple(testCases, baseTestName = "generated") {
|
|
156
|
+
return testCases
|
|
157
|
+
.map((testCase, index) => {
|
|
158
|
+
const testName = `${baseTestName}_${index + 1}`
|
|
159
|
+
return formatTestCase(testCase, testName)
|
|
160
|
+
})
|
|
161
|
+
.join("\n\n")
|
|
162
|
+
}
|