Created
February 20, 2019 15:13
-
-
Save KaNiShi/cfa07e956021851ecf1b6756178865b1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<title>Json2KotlinxSerializationDataClass</title> | |
<style> | |
textarea { | |
width: 48vw; | |
height: 32vw; | |
} | |
</style> | |
<script> | |
window.onload = function () { | |
document.getElementById('convert').onclick = function () { | |
let jsonValue = document.getElementById('json').value; | |
let kotlinArea = document.getElementById('kotlin'); | |
try { | |
let json = JSON.parse(jsonValue); | |
classCount = 1; | |
if (!Array.isArray(json)) { | |
let kotlinClass = `import kotlinx.serialization.SerialName\nimport kotlinx.serialization.Serializable\n\n`; | |
kotlinClass += createObjectClass(json); | |
kotlinArea.textContent = kotlinClass; | |
} else { | |
kotlinArea.textContent = 'エラー\n未対応の形式です' | |
} | |
} catch (e) { | |
kotlinArea.textContent = `エラー\n${e}`; | |
} | |
} | |
} | |
let className = 'Untitled'; | |
let classCount = 1; | |
let classTab = ' '; | |
const KOTLIN_CLASS_ANY = 'Any'; | |
const KOTLIN_CLASS_BOOLEAN = 'Boolean'; | |
const KOTLIN_CLASS_CHAR = 'Char'; | |
const KOTLIN_CLASS_BYTE = 'Byte'; | |
const KOTLIN_CLASS_INT = 'Int'; | |
const KOTLIN_CLASS_LONG = 'Long'; | |
const KOTLIN_CLASS_FLOAT = 'Float'; | |
const KOTLIN_CLASS_DOUBLE = 'Double'; | |
const KOTLIN_CLASS_STRING = 'String'; | |
const KOTLIN_CLASS_LIST = 'List'; | |
function createObjectClass(items) { | |
let classData = { className: `${className}${classCount++}`, params: [], otherClass: [] }; | |
for (let index in items) { | |
let item = items[index]; | |
switch (typeof item) { | |
case 'boolean': | |
classData.params.push({ name: index, type: KOTLIN_CLASS_BOOLEAN, nullable: false }); | |
break; | |
case 'number': | |
if (Number.isInteger(item)) { | |
if (item > 2147483647 || item < -2147483648) { | |
classData.params.push({ name: index, type: KOTLIN_CLASS_LONG, nullable: false }); | |
} else { | |
classData.params.push({ name: index, type: KOTLIN_CLASS_INT, nullable: false }); | |
} | |
} else { | |
classData.params.push({ name: index, type: KOTLIN_CLASS_DOUBLE, nullable: false }); | |
} | |
break; | |
case 'string': | |
classData.params.push({ name: index, type: KOTLIN_CLASS_STRING, nullable: false }); | |
break; | |
case 'object': | |
if (Array.isArray(item)) { | |
let listClassData = createArrayClass(item); | |
classData.params.push({ name: index, type: `${KOTLIN_CLASS_LIST}<${listClassData.className}${listClassData.nullable?'?':''}>`, nullable: false }); | |
if(listClassData.otherClass != null) classData.otherClass.push(listClassData.otherClass); | |
} else { | |
if (item === null) { | |
classData.params.push({ name: index, type: KOTLIN_CLASS_ANY, nullable: true }); | |
} else { | |
classData.params.push({ name: index, type: `${className}${classCount}`, nullable: false }); | |
classData.otherClass.push(createObjectClass(item)); | |
} | |
} | |
break; | |
} | |
} | |
let kotlinClass = `@Serializable\ndata class ${classData.className}(`; | |
for (let member of classData.params) { | |
kotlinClass += `\n${createMemberParam(member)},`; | |
} | |
kotlinClass = kotlinClass.substring(0, kotlinClass.length - 1); | |
kotlinClass += '\n)\n'; | |
for (let otherClass of classData.otherClass) { | |
kotlinClass += `\n${otherClass}\n`; | |
} | |
return kotlinClass; | |
} | |
function createArrayClass(items) { | |
let classData = { className: null, dataClass: null, nullable: false, otherClass: null }; | |
for (let item of items) { | |
switch (typeof item) { | |
case 'boolean': | |
classData.className = checkClassMache(classData.className, KOTLIN_CLASS_BOOLEAN); | |
break; | |
case 'number': | |
if (Number.isInteger(item)) { | |
if (item > 2147483647 || item < -2147483648) { | |
classData.className = checkClassMache(classData.className, KOTLIN_CLASS_LONG); | |
} else { | |
classData.className = checkClassMache(classData.className, KOTLIN_CLASS_INT); | |
} | |
} else { | |
classData.className = checkClassMache(classData.className, KOTLIN_CLASS_DOUBLE); | |
} | |
break; | |
case 'string': | |
classData.className = checkClassMache(classData.className, KOTLIN_CLASS_STRING); | |
break; | |
case 'object': | |
if (Array.isArray(item)) { | |
} else if (item != null) { | |
} else { | |
classData.nullable = true; | |
} | |
break; | |
} | |
} | |
return classData; | |
} | |
function checkClassMache(currentClass, targetClass) { | |
if (currentClass == null) { | |
return targetClass; | |
} else if (currentClass != targetClass) { | |
if (targetClass == KOTLIN_CLASS_LONG) { | |
if (currentClass == KOTLIN_CLASS_INT) { | |
return targetClass | |
} else { | |
return KOTLIN_CLASS_ANY | |
} | |
} else if (targetClass == KOTLIN_CLASS_DOUBLE) { | |
if (currentClass == KOTLIN_CLASS_INT || currentClass == KOTLIN_CLASS_LONG || currentClass == KOTLIN_CLASS_FLOAT) { | |
return targetClass | |
} else { | |
return KOTLIN_CLASS_ANY | |
} | |
} else { | |
return KOTLIN_CLASS_ANY; | |
} | |
} else { | |
return currentClass; | |
} | |
} | |
function createMemberParam(params) { | |
return `${classTab}@SerialName("${params.name}")\n${classTab}val ${createMemberName(params.name)}: ${params.type}${params.nullable ? '?' : ''}`; | |
} | |
function createMemberName(name) { | |
let splitName = name.split('_'); | |
let memberName = splitName[0]; | |
for (let i = 1; i < splitName.length; i++) { | |
let text = splitName[i]; | |
memberName += text.charAt(0).toUpperCase() + text.slice(1); | |
} | |
return memberName; | |
} | |
</script> | |
</head> | |
<body> | |
<h1>Json2KotlinxSerializationDataClass</h1> | |
<div><textarea id="json" placeholder="Json"></textarea></div> | |
<div><button id="convert">↓</button></div> | |
<div><textarea id="kotlin" placeholder="Kotlin" readonly></textarea></div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment