Created
October 19, 2016 07:39
-
-
Save gzoritchak/facabe61903545a578208b486f069c6b to your computer and use it in GitHub Desktop.
The code of the DSL live coding in Lyon https://www.meetup.com/fr-FR/Lyon-Kotlin-User-Group/events/234673830/?eventId=234673830
This file contains 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
package jug.dsl | |
val kotlinSurveyDef = createNewSurveyDef("Évaluation du kotlin user group") { | |
introduction = "Merci de prendre 20 secondes pour répondre à quelques questions." | |
val appreciation = intQuestion("Quelle est votre appréciation de la dernière session ?"){ | |
min = 1 | |
max = 5 | |
} | |
booleanQuestion("Seriez vous prêt à recommander ce meetup à vos connaissances ?"){ | |
showIf = { (valueOf(appreciation))> 3} | |
} | |
} | |
fun createNewSurveyDef(title: String, init:SurveyDef.() -> Unit) = SurveyDef(title).apply { | |
init() | |
} | |
fun main(args: Array<String>) { | |
val survey = kotlinSurveyDef.newSurvey() | |
survey.start() | |
} | |
class SurveyDef(val title: String){ | |
var introduction = "" | |
val questionDefs = mutableListOf<QuestionDef<*>>() | |
fun newSurvey() = Survey(this) | |
fun intQuestion(title: String, init: IntQuestionDef.() -> Unit) = IntQuestionDef(title).apply { | |
init() | |
questionDefs += this | |
} | |
fun booleanQuestion(title: String, init: BooleanQuestionDef.() -> Unit) = BooleanQuestionDef(title).apply { | |
init() | |
questionDefs += this | |
} | |
} | |
abstract class QuestionDef<T>(val title: String){ | |
abstract fun consignes(): String | |
abstract fun toValue(userInput: String):T | |
var showIf: Survey.()->Boolean = {true} | |
} | |
class BooleanQuestionDef(title: String):QuestionDef<Boolean>(title){ | |
override fun consignes() = "Saisir O ou N" | |
override fun toValue(userInput: String) = when(userInput){ | |
"N", "n" -> false | |
"O", "o" -> true | |
else -> error("SAISIR O ou N !!!") | |
} | |
} | |
class IntQuestionDef(title: String):QuestionDef<Int>(title){ | |
override fun toValue(userInput: String): Int { | |
try { | |
val value = userInput.toInt() | |
if(value>max) error("Saisir un entien inférieur à $max") | |
if(value<min) error("Saisir un entien supérieur à $min") | |
return value | |
} catch(e: NumberFormatException) { | |
error("Saisir un entien") | |
} | |
} | |
override fun consignes() = "Saisir un entier entre $min et $max" | |
var min = Int.MIN_VALUE | |
var max = Int.MAX_VALUE | |
} | |
class Survey(val surveyDef: SurveyDef){ | |
var status = SurveyStatus.ONGOING | |
val answers = mutableListOf<Answer>() | |
var questionIdx = 0 | |
val currentQuestionDef : QuestionDef<*> | |
get() = surveyDef.questionDefs[questionIdx] | |
inline fun <reified T> valueOf(questionDef: QuestionDef<T>) = | |
answers.filterIsInstance(Answer.AnswerWithValue::class.java) | |
.first{it.questionDef == questionDef}.value as T | |
fun start(){ | |
println(surveyDef.title) | |
println(surveyDef.introduction) | |
while (status == SurveyStatus.ONGOING){ | |
if(currentQuestionDef.showIf(this) == false){ | |
nextQuestion() | |
continue | |
} | |
println(currentQuestionDef.title) | |
println(currentQuestionDef.consignes()) | |
val userInput = readLine()!! | |
try { | |
val value = currentQuestionDef.toValue(userInput) | |
answers += | |
if(value == null) Answer.AnswerWithoutValue(currentQuestionDef) | |
else Answer.AnswerWithValue(currentQuestionDef, value) | |
nextQuestion() | |
} catch(e: Exception) { | |
System.err.println(e.message) | |
} | |
} | |
} | |
private fun nextQuestion() { | |
questionIdx++ | |
if (questionIdx == surveyDef.questionDefs.size) { | |
status = SurveyStatus.COMPLETED | |
} | |
} | |
} | |
sealed class Answer(val questionDef: QuestionDef<*>){ | |
class AnswerWithValue(questionDef: QuestionDef<*>, val value: Any):Answer(questionDef) | |
class AnswerWithoutValue(questionDef: QuestionDef<*>):Answer(questionDef) | |
} | |
enum class SurveyStatus {ONGOING, COMPLETED} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment