DeriveToCaseClass.scala 4.0 KB
Newer Older
梦境迷离's avatar
fix  
梦境迷离 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Copyright (c) 2022 bitlap
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

梦境迷离's avatar
fix  
梦境迷离 已提交
22
package org.bitlap.csv.core.macros
梦境迷离's avatar
fix  
梦境迷离 已提交
23

梦境迷离's avatar
add csv  
梦境迷离 已提交
24 25 26 27 28 29 30 31
import scala.reflect.macros.blackbox

/**
 * @author 梦境迷离
 * @version 1.0,2022/4/29
 */
object DeriveToCaseClass {

梦境迷离's avatar
fix  
梦境迷离 已提交
32
  def apply[T <: Product](line: String, columnSeparator: Char): Option[T] = macro Macro.macroImpl[T]
梦境迷离's avatar
add csv  
梦境迷离 已提交
33 34

  class Macro(override val c: blackbox.Context) extends AbstractMacroProcessor(c) {
梦境迷离's avatar
fix  
梦境迷离 已提交
35 36 37 38
    import c.universe._

    private val packageName = q"_root_.org.bitlap.csv.core"

梦境迷离's avatar
fix  
梦境迷离 已提交
39
    def macroImpl[T <: Product: c.WeakTypeTag](
梦境迷离's avatar
fix  
梦境迷离 已提交
40
      line: c.Expr[String],
梦境迷离's avatar
fix  
梦境迷离 已提交
41 42
      columnSeparator: c.Expr[Char]
    ): c.Expr[Option[T]] = {
梦境迷离's avatar
add csv  
梦境迷离 已提交
43
      val clazzName = c.weakTypeOf[T].typeSymbol.name
梦境迷离's avatar
fix  
梦境迷离 已提交
44
      val innerVarTermName = TermName("_columns")
梦境迷离's avatar
fix  
梦境迷离 已提交
45 46 47 48 49 50 51
      val fields = (columns: TermName) =>
        checkCaseClassZipParams[T](columns).map { idxType =>
          val columnValues = idxType._1._2
          if (idxType._2 <:< typeOf[Option[_]]) {
            val genericType = c.typecheck(q"${idxType._2}", c.TYPEmode).tpe.typeArgs.head
            q"$packageName.Converter[${genericType.typeSymbol.name.toTypeName}].toScala($columnValues)"
          } else {
梦境迷离's avatar
fix  
梦境迷离 已提交
52
            val caseClassFieldTypeName = TypeName(idxType._2.typeSymbol.name.decodedName.toString)
梦境迷离's avatar
fix  
梦境迷离 已提交
53 54
            idxType._2 match {
              case t if t =:= typeOf[Int] =>
梦境迷离's avatar
fix  
梦境迷离 已提交
55
                q"$packageName.Converter[$caseClassFieldTypeName].toScala($columnValues).getOrElse(0)"
梦境迷离's avatar
fix  
梦境迷离 已提交
56
              case t if t =:= typeOf[String] =>
梦境迷离's avatar
fix  
梦境迷离 已提交
57
                q"""$packageName.Converter[$caseClassFieldTypeName].toScala($columnValues).getOrElse("")"""
梦境迷离's avatar
fix  
梦境迷离 已提交
58
              case t if t =:= typeOf[Float] =>
梦境迷离's avatar
fix  
梦境迷离 已提交
59
                q"$packageName.Converter[$caseClassFieldTypeName].toScala($columnValues).getOrElse(0F)"
梦境迷离's avatar
fix  
梦境迷离 已提交
60
              case t if t =:= typeOf[Double] =>
梦境迷离's avatar
fix  
梦境迷离 已提交
61
                q"$packageName.Converter[$caseClassFieldTypeName].toScala($columnValues).getOrElse(0D)"
梦境迷离's avatar
fix  
梦境迷离 已提交
62
              case t if t =:= typeOf[Char] =>
梦境迷离's avatar
fix  
梦境迷离 已提交
63
                q"$packageName.Converter[$caseClassFieldTypeName].toScala($columnValues).getOrElse('?')"
梦境迷离's avatar
fix  
梦境迷离 已提交
64
              case t if t =:= typeOf[Byte] =>
梦境迷离's avatar
fix  
梦境迷离 已提交
65
                q"$packageName.Converter[$caseClassFieldTypeName].toScala($columnValues).getOrElse(0)"
梦境迷离's avatar
fix  
梦境迷离 已提交
66
              case t if t =:= typeOf[Short] =>
梦境迷离's avatar
fix  
梦境迷离 已提交
67
                q"$packageName.Converter[$caseClassFieldTypeName].toScala($columnValues).getOrElse(0)"
梦境迷离's avatar
fix  
梦境迷离 已提交
68
              case t if t =:= typeOf[Boolean] =>
梦境迷离's avatar
fix  
梦境迷离 已提交
69
                q"$packageName.Converter[$caseClassFieldTypeName].toScala($columnValues).getOrElse(false)"
梦境迷离's avatar
fix  
梦境迷离 已提交
70
              case t if t =:= typeOf[Long] =>
梦境迷离's avatar
fix  
梦境迷离 已提交
71
                q"$packageName.Converter[$caseClassFieldTypeName].toScala($columnValues).getOrElse(0L)"
梦境迷离's avatar
fix  
梦境迷离 已提交
72
            }
梦境迷离's avatar
add csv  
梦境迷离 已提交
73 74 75 76
          }
        }
      val tree =
        q"""
梦境迷离's avatar
fix  
梦境迷离 已提交
77 78 79 80
           lazy val $innerVarTermName = _root_.org.bitlap.csv.core.StringUtils.splitColumns($line, $columnSeparator)
           Option(${TermName(clazzName.decodedName.toString)}(..${fields(innerVarTermName)}))
           """
      printTree[T](force = false, tree)
梦境迷离's avatar
add csv  
梦境迷离 已提交
81 82 83 84 85

    }.asInstanceOf[c.Expr[Option[T]]]

  }
}