I wrote a parser that converts String to Seq [String], following some rules. It will be used in the library.
I am trying to convert this Seq [String] to the case class. The case class will be provided by the user (so there is no way to guess what it will be).
I thought of a shapeless library because it seems to implement good features and seems mature, but I have no idea how to proceed.
I found this question with an interesting answer , but I do not find how to convert it for my needs. In fact, the answer has only one type for parsing (String), and the library iterates inside the string itself. This probably requires profound changes in how this is done, and I don't know how to do it.
In addition, if possible, I want to make this process as simple as possible for the user of my library. Therefore, if possible, unlike the answer in the link above, the HList type will be guessed from the case class itself (however, according to my search, it seems that the compiler needs this information).
I am a little new to the type system and all these wonderful things, if someone can give me advice on how to do this, I would be very happy!
Yours faithfully
--- EDIT ---
As requested by ziggystar, here are some of the possible signatures:
//Let say we are just parsing a CSV. @onUserSide case class UserClass(i:Int, j:Int, s:String) val list = Seq("1,2,toto", "3,4,titi") // User transforms his case class to a function with something like: val f = UserClass.curried // The function created in 1/ is injected in the parser val parser = new Parser(f) // The Strings to convert to case classes are provided as an argument to the parse() method. val finalResult:Seq[UserClass] = parser.parse(list) // The transfomation is done in two steps inside the parse() method: // 1/ first we have: val list = Seq("1,2,toto", "3,4,titi") // 2/ then we have a call to internalParserImplementedSomewhereElse(list) // val parseResult is now equal to Seq(Seq("1", "2", "toto"), Seq("3","4", "titi")) // 3/ finally Shapeless do its magick trick and we have Seq(UserClass(1,2,"toto"), UserClass(3,4,"titi)) @insideTheLibrary class Parser[A](function:A) { //The internal parser takes each String provided through argument of the method and transforms each String to a Seq[String]. So the Seq[String] provided is changed to Seq[Seq[String]]. private def internalParserImplementedSomewhereElse(l:Seq[String]): Seq[Seq[String]] = { ... } /* * Class A and B are both related to the case class provided by the user: * - A is the type of the case class as a function, * - B is the type of the original case class (can be guessed from type A). */ private def convert2CaseClass[B](list:Seq[String]): B { //do something with Shapeless //I don't know what to put inside ??? } def parse(l:Seq[String]){ val parseResult:Seq[Seq[String]] = internalParserImplementedSomewhereElse(l:Seq[String]) val finalResult = result.map(convert2CaseClass) finalResult // it is a Seq[CaseClassProvidedByUser] } }
Inside the library, some implicit ones will be available for converting String to the correct type, as Shapeless guesses (similar to what was suggested in the link above). Like string.toInt, string.ToDouble, etc.
Maybe there is another way to develop it. This is what I mean after playing with Shapeless for several hours.