├── .github └── workflows │ ├── ci.yml │ └── clean.yml ├── .gitignore ├── .scalafmt.conf ├── .travis.yml ├── LICENSE ├── README.md ├── build.sbt ├── examples ├── build.sbt └── src │ └── main │ ├── scala-2 │ └── zsg │ │ ├── sample01_append │ │ └── Sample01.scala │ │ ├── sample02_generic │ │ └── Sample02.scala │ │ ├── sample03_macros_code_generation │ │ ├── Foo.scala │ │ ├── Sample10.scala │ │ ├── Sample11.scala │ │ ├── ZsgDefaultValueGenericCodeGenSample.scala │ │ └── ZsgGenericCodeGenSample.scala │ │ └── sample04_round │ │ └── Round1.scala │ └── scala-21111 │ └── asuna │ └── sample03_macros_code_generation │ ├── ZsgGetterGenericCodeGenSample.scala │ ├── ZsgLabelledGenericCodeGenSample.scala │ ├── ZsgSealedClassGenericCodeGenSample.scala │ ├── ZsgSealedGenericCodeGenSample.scala │ ├── ZsgSealedLabelledGenericCodeGenSample.scala │ ├── ZsgSetterGenericCodeGenSample.scala │ └── deficient │ ├── AsunaTupleApplyCodeGenSample.scala1111 │ ├── AsunaTupleGenericCodeGenSample.scala1111 │ ├── AsunaTupleGetterGenericCodeGenSample.scala1111 │ └── AsunaTupleLabelledGenericCodeGenSample.scala1111 ├── modules ├── benchmark │ ├── build.sbt │ └── src │ │ └── main │ │ ├── resources │ │ └── simplelogger.properties │ │ └── scala │ │ └── zsg │ │ └── json │ │ ├── encoder │ │ └── benchmark │ │ │ ├── JsonADTEncoderBenchmark.scala │ │ │ └── JsonEncoderBenchmark.scala │ │ └── model │ │ ├── adt │ │ ├── ADTBenchmarkModel.scala │ │ └── ADTNodel.scala │ │ └── case_class │ │ ├── Bar.scala │ │ ├── BenchmarkModel.scala │ │ └── Foo.scala ├── codegen │ ├── build.sbt │ └── src │ │ └── main │ │ ├── scala │ │ └── zsg │ │ │ └── codegen │ │ │ ├── DeleteTemp.scala │ │ │ ├── StringUtil.scala │ │ │ ├── ZsgCoreCodeGeneration.scala │ │ │ ├── ZsgParameters.scala │ │ │ ├── ZsgScalaTupleCodeGeneration.scala │ │ │ ├── ZsgTestKitCodeGeneration.scala │ │ │ └── helper │ │ │ └── TreeHelper.scala │ │ └── twirl │ │ └── zsg │ │ ├── codegen │ │ ├── scalaTuple │ │ │ ├── ScalaTuple_Scala2_Implicit.scala.txt │ │ │ ├── ScalaTuple_Scala2_TuplePlus.scala.txt │ │ │ └── ScalaTuple_Scala2_TypeHList.scala.txt │ │ ├── testkit │ │ │ └── CaseClassTestKit.scala.txt │ │ └── tuple │ │ │ ├── TagMerge.scala.txt │ │ │ └── TypeHListX.scala.txt │ │ └── scala3Codegen │ │ ├── scalaTuple │ │ ├── ScalaTuple_Scala3_Implicit.scala.txt │ │ ├── ScalaTuple_Scala3_TuplePlus.scala.txt │ │ └── ScalaTuple_Scala3_TypeHList.scala.txt │ │ ├── testkit │ │ └── CaseClassTestKit.scala.txt1111 │ │ └── tuple │ │ ├── TagMerge.scala.txt1111 │ │ └── TypeHListX.scala.txt ├── core │ ├── build.sbt │ ├── src │ │ ├── codegen │ │ │ ├── scala-2 │ │ │ │ └── zsg │ │ │ │ │ ├── TagMerge.scala │ │ │ │ │ └── TypeHListX.scala │ │ │ └── scala-3 │ │ │ │ └── zsg │ │ │ │ └── TypeHListX.scala │ │ └── main │ │ │ ├── scala-2 │ │ │ └── zsg │ │ │ │ ├── Application.scala │ │ │ │ ├── Context.scala │ │ │ │ ├── Item2TypeHList.scala │ │ │ │ ├── Plus.scala │ │ │ │ ├── TypeFunction.scala │ │ │ │ └── TypeHList.scala │ │ │ ├── scala-3 │ │ │ └── zsg │ │ │ │ ├── Application.scala │ │ │ │ ├── Context.scala │ │ │ │ ├── Item2TypeHList.scala │ │ │ │ ├── Plus.scala │ │ │ │ └── TypeHList.scala │ │ │ └── scala │ │ │ └── zsg │ │ │ ├── ItemTag2.scala │ │ │ ├── PlaceHolder.scala │ │ │ ├── PropertyTag.scala │ │ │ └── ZsgTuple2.scala │ └── version.sbt ├── macros │ ├── build.sbt │ ├── src │ │ ├── main │ │ │ ├── scala-2.11-2.12 │ │ │ │ └── zsg │ │ │ │ │ └── macros │ │ │ │ │ ├── ByNameImplicit.scala │ │ │ │ │ └── utils │ │ │ │ │ ├── GenericColumnName.scala │ │ │ │ │ └── MacroMethods.scala │ │ │ ├── scala-2.13 │ │ │ │ └── zsg │ │ │ │ │ └── macros │ │ │ │ │ ├── ByNameImplicit.scala │ │ │ │ │ └── utils │ │ │ │ │ ├── GenericColumnName.scala │ │ │ │ │ └── MacroMethods.scala │ │ │ ├── scala-2 │ │ │ │ └── zsg │ │ │ │ │ └── macros │ │ │ │ │ ├── AllScalaMacroMethods.scala │ │ │ │ │ ├── multiply │ │ │ │ │ ├── RootTable.scala │ │ │ │ │ ├── ZsgMultiplyGeneric.scala │ │ │ │ │ ├── ZsgMultiplyRepGeneric.scala │ │ │ │ │ └── utils │ │ │ │ │ │ └── PropertyOverrideHelper.scala │ │ │ │ │ └── single │ │ │ │ │ ├── ZsgDefaultValueGeneric.scala │ │ │ │ │ ├── ZsgGeneric.scala │ │ │ │ │ ├── ZsgGetterGeneric.scala │ │ │ │ │ ├── ZsgLabelledGeneric.scala │ │ │ │ │ ├── ZsgLabelledTypeGeneric.scala │ │ │ │ │ ├── ZsgSealedClassGeneric.scala │ │ │ │ │ ├── ZsgSealedGeneric.scala │ │ │ │ │ ├── ZsgSealedLabelledGeneric.scala │ │ │ │ │ ├── ZsgSetterGeneric.scala │ │ │ │ │ ├── deficient │ │ │ │ │ ├── AsunaTupleApply.scala │ │ │ │ │ ├── AsunaTupleGeneric.scala │ │ │ │ │ ├── AsunaTupleGetterGeneric.scala │ │ │ │ │ ├── AsunaTupleLabelledGeneric.scala │ │ │ │ │ ├── DeficientProperty.scala │ │ │ │ │ └── ModelProperty.scala │ │ │ │ │ └── utils │ │ │ │ │ ├── SealedHelper.scala │ │ │ │ │ ├── Sha1Helper.scala │ │ │ │ │ └── TypeHelper.scala │ │ │ ├── scala-3 │ │ │ │ └── AsunaGeneric.scala │ │ │ └── scala │ │ │ │ └── zsg │ │ │ │ └── macros │ │ │ │ ├── ZsgParameters.scala │ │ │ │ └── single │ │ │ │ ├── ColumnName.scala │ │ │ │ ├── DebugColumnInfo.scala │ │ │ │ ├── InstanceApply.scala │ │ │ │ └── PropertyApply.scala │ │ ├── test │ │ │ ├── resources │ │ │ │ └── simplelogger.properties │ │ │ ├── scala-2.13 │ │ │ │ └── zsg │ │ │ │ │ └── test │ │ │ │ │ └── macros │ │ │ │ │ ├── CaseClassLabelledGenericMacroGenPrepareTest.scala │ │ │ │ │ └── CaseClassLabelledGenericMacroGenTest.scala │ │ │ ├── scala-2 │ │ │ │ └── zsg │ │ │ │ │ ├── macros │ │ │ │ │ └── case_class_test │ │ │ │ │ │ └── codegen │ │ │ │ │ │ ├── CaseClassTest1.scala │ │ │ │ │ │ ├── CaseClassTest160.scala │ │ │ │ │ │ ├── CaseClassTest2.scala │ │ │ │ │ │ ├── CaseClassTest3.scala │ │ │ │ │ │ ├── CaseClassTest4.scala │ │ │ │ │ │ └── CaseClassTest68.scala │ │ │ │ │ └── test │ │ │ │ │ └── macros │ │ │ │ │ ├── case_class_test │ │ │ │ │ ├── ModelFromString.scala │ │ │ │ │ ├── ModelFromStringImpl.scala │ │ │ │ │ ├── ModelToString.scala │ │ │ │ │ └── PropertyItem.scala │ │ │ │ │ ├── rep_encoder_test │ │ │ │ │ ├── MutiplyClassGenericPrepareTest.scala │ │ │ │ │ └── MutiplyClassGenericTest.scala │ │ │ │ │ └── sealed_trait_test │ │ │ │ │ ├── SealedTraitLabelledGenericPrepareTest.scala │ │ │ │ │ └── SealedTraitLabelledGenericTest.scala │ │ │ └── scala-3 │ │ │ │ └── MacroTest.scala │ │ └── test1 │ │ │ └── scala │ │ │ └── bb.scala │ └── version.sbt ├── rep │ ├── build.sbt │ ├── src │ │ ├── main │ │ │ └── scala │ │ │ │ └── zsg │ │ │ │ └── RepMerge.scala │ │ └── test │ │ │ └── scala │ │ │ └── zsg │ │ │ └── teskit │ │ │ └── rep1 │ │ │ ├── BooleanModel.scala │ │ │ ├── Description.scala │ │ │ ├── Rep1.scala │ │ │ ├── Rep1Test.scala │ │ │ ├── ReverseBoolean.scala │ │ │ └── RouteModel.scala │ └── version.sbt ├── scala-tuple │ ├── build.sbt │ ├── src │ │ ├── codegen │ │ │ ├── scala-2 │ │ │ │ └── zsg │ │ │ │ │ └── scala │ │ │ │ │ └── tuple │ │ │ │ │ ├── Tuple22Plus.scala │ │ │ │ │ ├── Tuple22TypeHList.scala │ │ │ │ │ └── TupleHelper.scala │ │ │ └── scala-3 │ │ │ │ └── zsg │ │ │ │ └── scala │ │ │ │ └── tuple │ │ │ │ ├── Tuple22Plus.scala │ │ │ │ ├── Tuple22TypeHList.scala │ │ │ │ └── TupleHelper.scala │ │ ├── main │ │ │ └── scala-3 │ │ │ │ └── zsg │ │ │ │ └── scala │ │ │ │ └── tuple │ │ │ │ ├── Tuple23Plus.scala │ │ │ │ └── TupleHelper23.scala │ │ └── test │ │ │ ├── scala-2 │ │ │ └── zsg │ │ │ │ └── testkit │ │ │ │ └── tuple │ │ │ │ ├── TupleToString.scala │ │ │ │ ├── TupleToStringTest.scala │ │ │ │ └── reverse │ │ │ │ ├── ReverseTupleToString.scala │ │ │ │ └── ReverseTupleToStringTest.scala │ │ │ ├── scala-3 │ │ │ └── zsg │ │ │ │ └── testkit │ │ │ │ └── tuple │ │ │ │ ├── Scala3TupleData.scala │ │ │ │ ├── TupleToString.scala │ │ │ │ ├── TupleToStringTest.scala │ │ │ │ ├── TupleToStringTest2.scala │ │ │ │ ├── TupleToStringTest3.scala │ │ │ │ └── reverse │ │ │ │ ├── ReverseTupleToString.scala │ │ │ │ └── ReverseTupleToStringTest.scala │ │ │ └── scala │ │ │ └── zsg │ │ │ └── testkit │ │ │ └── tuple │ │ │ ├── TupleData.scala │ │ │ └── reverse │ │ │ └── ReverseTupleData.scala │ └── version.sbt └── testkit │ ├── build.sbt │ ├── src │ ├── main │ │ ├── scala-2.11 │ │ │ └── CirceVersionCompat.scala │ │ ├── scala-2.12 │ │ │ └── CirceVersionCompat.scala │ │ ├── scala-2.13 │ │ │ └── CirceVersionCompat.scala │ │ └── scala-2 │ │ │ └── zsg │ │ │ └── testkit │ │ │ ├── circe │ │ │ ├── ACirce.scala │ │ │ ├── compare │ │ │ │ └── LargeModelTest.scala │ │ │ ├── decoder │ │ │ │ ├── JsonDecoderPro.scala │ │ │ │ ├── SealedTraitSelector.scala │ │ │ │ ├── ZsgDecoderContext.scala │ │ │ │ └── ZsgSealedContext.scala │ │ │ ├── encoder │ │ │ │ ├── JsonObjectAppender.scala │ │ │ │ ├── SealedTraitSelector.scala │ │ │ │ ├── Utils.scala │ │ │ │ ├── ZsgJsonObjectContext.scala │ │ │ │ └── ZsgSealedContext.scala │ │ │ └── shapeless │ │ │ │ └── ShapelessTest.scala │ │ │ └── model │ │ │ ├── CirceLargeModel.scala │ │ │ └── SimpleModel1.scala │ └── test │ │ └── scala-2 │ │ └── zsg │ │ └── testkit │ │ └── circe │ │ ├── test1 │ │ ├── CirceModel.scala │ │ ├── Instance.scala │ │ ├── ZsgCirceModel.scala │ │ └── ZsgWithCirceEncoderTest.scala │ │ ├── test2 │ │ ├── CirceModel.scala │ │ ├── Instance.scala │ │ ├── ZsgCirceModel.scala │ │ └── ZsgWithDecoderEncoderTest.scala │ │ └── test3 │ │ ├── Asuna.scala.1111 │ │ ├── AsunaWithDecoderEncoderTest.scala.1111 │ │ └── Instance.scala │ └── version.sbt ├── project ├── CommonSettings.scala ├── Dependencies.scala ├── ZsgSettings.scala ├── build.properties └── plugins.sbt └── version.sbt /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by sbt-github-actions using the 2 | # githubWorkflowGenerate task. You should add and commit this file to 3 | # your git repository. It goes without saying that you shouldn't edit 4 | # this file by hand! Instead, if you wish to make changes, you should 5 | # change your sbt build configuration to revise the workflow description 6 | # to meet your needs, then regenerate this file. 7 | 8 | name: Continuous Integration 9 | 10 | on: 11 | pull_request: 12 | branches: ['**'] 13 | push: 14 | branches: ['**'] 15 | 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | 19 | jobs: 20 | build: 21 | name: Build and Test 22 | strategy: 23 | matrix: 24 | os: [ubuntu-latest] 25 | scala: [2.12.14, 2.13.8, 3.1.1] 26 | java: [adopt-hotspot@8.0] 27 | runs-on: ${{ matrix.os }} 28 | steps: 29 | - name: Checkout current branch (full) 30 | uses: actions/checkout@v2 31 | with: 32 | fetch-depth: 0 33 | 34 | - name: Setup Java (adopt-hotspot@8.0) 35 | if: matrix.java == 'adopt-hotspot@8.0' 36 | uses: actions/setup-java@v2 37 | with: 38 | distribution: adopt-hotspot 39 | java-version: 8.0 40 | 41 | - name: Cache sbt 42 | uses: actions/cache@v2 43 | with: 44 | path: | 45 | ~/.sbt 46 | ~/.ivy2/cache 47 | ~/.coursier/cache/v1 48 | ~/.cache/coursier/v1 49 | ~/AppData/Local/Coursier/Cache/v1 50 | ~/Library/Caches/Coursier/v1 51 | key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} 52 | 53 | - name: Check that workflows are up to date 54 | run: sbt ++${{ matrix.scala }} githubWorkflowCheck 55 | 56 | - name: Test 57 | run: sbt ++${{ matrix.scala }} clean coverage test 58 | 59 | - name: Coverage 60 | run: sbt ++${{ matrix.scala }} coverageReport 61 | 62 | - uses: codecov/codecov-action@v1 63 | -------------------------------------------------------------------------------- /.github/workflows/clean.yml: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by sbt-github-actions using the 2 | # githubWorkflowGenerate task. You should add and commit this file to 3 | # your git repository. It goes without saying that you shouldn't edit 4 | # this file by hand! Instead, if you wish to make changes, you should 5 | # change your sbt build configuration to revise the workflow description 6 | # to meet your needs, then regenerate this file. 7 | 8 | name: Clean 9 | 10 | on: push 11 | 12 | jobs: 13 | delete-artifacts: 14 | name: Delete Artifacts 15 | runs-on: ubuntu-latest 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | steps: 19 | - name: Delete artifacts 20 | run: | 21 | # Customize those three lines with your repository and credentials: 22 | REPO=${GITHUB_API_URL}/repos/${{ github.repository }} 23 | 24 | # A shortcut to call GitHub API. 25 | ghapi() { curl --silent --location --user _:$GITHUB_TOKEN "$@"; } 26 | 27 | # A temporary file which receives HTTP response headers. 28 | TMPFILE=/tmp/tmp.$$ 29 | 30 | # An associative array, key: artifact name, value: number of artifacts of that name. 31 | declare -A ARTCOUNT 32 | 33 | # Process all artifacts on this repository, loop on returned "pages". 34 | URL=$REPO/actions/artifacts 35 | while [[ -n "$URL" ]]; do 36 | 37 | # Get current page, get response headers in a temporary file. 38 | JSON=$(ghapi --dump-header $TMPFILE "$URL") 39 | 40 | # Get URL of next page. Will be empty if we are at the last page. 41 | URL=$(grep '^Link:' "$TMPFILE" | tr ',' '\n' | grep 'rel="next"' | head -1 | sed -e 's/.*.*//') 42 | rm -f $TMPFILE 43 | 44 | # Number of artifacts on this page: 45 | COUNT=$(( $(jq <<<$JSON -r '.artifacts | length') )) 46 | 47 | # Loop on all artifacts on this page. 48 | for ((i=0; $i < $COUNT; i++)); do 49 | 50 | # Get name of artifact and count instances of this name. 51 | name=$(jq <<<$JSON -r ".artifacts[$i].name?") 52 | ARTCOUNT[$name]=$(( $(( ${ARTCOUNT[$name]} )) + 1)) 53 | 54 | id=$(jq <<<$JSON -r ".artifacts[$i].id?") 55 | size=$(( $(jq <<<$JSON -r ".artifacts[$i].size_in_bytes?") )) 56 | printf "Deleting '%s' #%d, %'d bytes\n" $name ${ARTCOUNT[$name]} $size 57 | ghapi -X DELETE $REPO/actions/artifacts/$id 58 | done 59 | done 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *target 2 | /.idea 3 | /logs 4 | _site 5 | /sbt 6 | /sbt.bat 7 | /sbt-launch.jar 8 | /.dotty-ide.json 9 | /.dotty-ide-artifact 10 | /credentials 11 | /.metals 12 | /.bloop 13 | /project/.bloop 14 | /.bsp 15 | /.vscode 16 | /project/project 17 | /null 18 | metals.sbt -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | maxColumn = 140 2 | align.preset = more 3 | continuationIndent.defnSite = 2 4 | lineEndings = unix 5 | optIn.breakChainOnFirstMethodDot = false 6 | rewrite.rules = [SortImports] 7 | version = 3.4.2 8 | fileOverride { 9 | "glob:**/scala-3*/**" { 10 | runner.dialect = scala3 11 | } 12 | } 13 | runner.dialect = scala213 -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: scala 2 | sudo: required 3 | dist: trusty 4 | 5 | scala: 6 | - 2.13.1 7 | 8 | jdk: 9 | - oraclejdk8 10 | 11 | cache: 12 | directories: 13 | - $HOME/.ivy2/cache 14 | - $HOME/.sbt/boot 15 | - $HOME/.coursier 16 | 17 | before_install: 18 | - pip install --user codecov 19 | 20 | script: 21 | - sbt +test 22 | - sbt clean coverage test coverageReport 23 | 24 | after_success: 25 | - bash <(curl -s https://codecov.io/bash) 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2018, 水山清风 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | zsg 2 | =========================================== 3 | [![Build status](https://img.shields.io/github/workflow/status/scalax/zsg/Continuous%20Integration.svg)](https://github.com/scalax/zsg/actions) 4 | [![codecov](https://codecov.io/gh/scalax/zsg/branch/master/graph/badge.svg)](https://codecov.io/gh/scalax/zsg) 5 | 6 | Yet another Scala generic library. -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | val rootDir = file(".") 2 | val modulesDir = rootDir / "modules" 3 | 4 | val core = project in modulesDir / "core" 5 | val rep = (project in modulesDir / "rep").dependsOn(core) 6 | val macros = (project in modulesDir / "macros").dependsOn(core) 7 | val scalaTuple = (project in modulesDir / "scala-tuple").dependsOn(core) 8 | 9 | val codegen = project in modulesDir / "codegen" 10 | val testkit = (project in modulesDir / "testkit").dependsOn(macros) 11 | val examples = (project in rootDir / "examples").dependsOn(testkit) 12 | val benchmark = (project in modulesDir / "benchmark").dependsOn(testkit) 13 | 14 | val zsg = (project in rootDir).dependsOn(core, testkit).aggregate(core, rep, macros, scalaTuple, testkit) 15 | 16 | ZsgSettings.settings.scalaVersion 17 | CommonSettings.settings 18 | ZsgSettings.settings.githubWorkflow 19 | 20 | val eachFmt = taskKey[Unit]("fmt for each project") 21 | eachFmt := { 22 | (IntegrationTest / scalafmtSbt).value 23 | (Compile / scalafmt).value 24 | (Test / scalafmt).value 25 | } 26 | addCommandAlias("fmt", "all eachFmt") 27 | addCommandAlias("codegen", s"++${ZsgSettings.versions.currentScala}! codegenTask") 28 | 29 | val codegenTask = inputKey[Unit]("codegen task") 30 | codegenTask := { 31 | (codegen / Compile / runMain).inputTaskValue.partialInput(" zsg.codegen.ZsgTestKitCodeGeneration").evaluated 32 | (codegen / Compile / runMain).inputTaskValue.partialInput(" zsg.codegen.ZsgCoreCodeGeneration").evaluated 33 | (codegen / Compile / runMain).inputTaskValue.partialInput(" zsg.codegen.ZsgScalaTupleCodeGeneration").evaluated 34 | } 35 | 36 | val deleteCodegen = inputKey[Unit]("delete codegen task") 37 | deleteCodegen := (codegen / Compile / runMain).inputTaskValue.partialInput(" zsg.codegen.DeleteTemp").evaluated 38 | 39 | val jmh1 = inputKey[Unit]("jmh1 task") 40 | val jmh2 = inputKey[Unit]("jmh2 task") 41 | 42 | jmh1 := (benchmark / Jmh / run).inputTaskValue 43 | .partialInput(" -i") 44 | .partialInput(" 3") 45 | .partialInput(" -wi") 46 | .partialInput(" 3") 47 | .partialInput(" -f") 48 | .partialInput(" 1") 49 | .partialInput(" -t") 50 | .partialInput(" 1") 51 | .partialInput(" zsg.json.encoder.benchmark.JsonEncoderBenchmark.*") 52 | .evaluated 53 | jmh2 := (benchmark / Jmh / run).inputTaskValue 54 | .partialInput(" -i") 55 | .partialInput(" 3") 56 | .partialInput(" -wi") 57 | .partialInput(" 3") 58 | .partialInput(" -f") 59 | .partialInput(" 1") 60 | .partialInput(" -t") 61 | .partialInput(" 1") 62 | .partialInput(" zsg.json.encoder.benchmark.JsonADTEncoderBenchmark.*") 63 | .evaluated 64 | -------------------------------------------------------------------------------- /examples/build.sbt: -------------------------------------------------------------------------------- 1 | ZsgSettings.settings.scalaVersion 2 | CommonSettings.settings 3 | 4 | libraryDependencies ++= Dependencies.circeDependencies(scalaVersion.value) 5 | libraryDependencies += Dependencies.scalaCollectionCompat 6 | -------------------------------------------------------------------------------- /examples/src/main/scala-2/zsg/sample03_macros_code_generation/Foo.scala: -------------------------------------------------------------------------------- 1 | package zsg.sample03_macros_code_generation 2 | 3 | sealed trait Foo 4 | 5 | class Bar1 extends Foo 6 | case class Bar2(ii: String) extends Foo 7 | class Bar3(val age: Int) extends Foo 8 | case class Bar4() extends Foo 9 | -------------------------------------------------------------------------------- /examples/src/main/scala-2/zsg/sample03_macros_code_generation/Sample10.scala: -------------------------------------------------------------------------------- 1 | package zsg.sample03_macros_code_generation 2 | 3 | case class Sample10( 4 | i1: String, 5 | i2: Int, 6 | i3: Int, 7 | i4: Long, 8 | i5: String = "Test10-i5", 9 | i6: List[String] = List.empty, 10 | i7: Long, 11 | i8: Option[Long], 12 | i9: List[Long], 13 | i10: String 14 | ) 15 | -------------------------------------------------------------------------------- /examples/src/main/scala-2/zsg/sample03_macros_code_generation/Sample11.scala: -------------------------------------------------------------------------------- 1 | package zsg.sample03_macros_code_generation 2 | 3 | trait Model10TraitI { 4 | self: SumTrait with SumIII => 5 | 6 | case class Sample10ModelWithDefaultValue( 7 | i1: String, 8 | i2: Int, 9 | i3: Int, 10 | i4: Long, 11 | i5: String = "Test10-i5", 12 | i6: List[SumII.Aux[Char]] = List.fill(5)(new SumII { 13 | override type ChartType = Char 14 | override def toString: String = s"${classOf[SumII]}.Aux[${classOf[ChartType]}]" 15 | }), 16 | i7: Long, 17 | i8: Option[Long] = Option(22), 18 | i9: List[Long], 19 | i10: String 20 | ) 21 | 22 | } 23 | 24 | trait SumIII 25 | 26 | trait SumII { 27 | type ChartType 28 | } 29 | 30 | object SumII { 31 | type Aux[T] = SumII { type ChartType = T } 32 | } 33 | 34 | trait SumTrait extends Model10TraitI with SumIII 35 | 36 | object sumOfCaseClass 37 | extends { 38 | val bb = 11 39 | } 40 | with SumTrait 41 | -------------------------------------------------------------------------------- /examples/src/main/scala-2/zsg/sample03_macros_code_generation/ZsgDefaultValueGenericCodeGenSample.scala: -------------------------------------------------------------------------------- 1 | package zsg.sample03_macros_code_generation 2 | 3 | import zsg._ 4 | import zsg.macros.single.{DefaultValue, ZsgDefaultValueGeneric} 5 | import scala.collection.compat._ 6 | 7 | object ZsgDefaultValueGenericCodeGenSample { 8 | 9 | import sumOfCaseClass._ 10 | 11 | def sameType[T](t1: T, t2: T): T = t1 12 | 13 | def genResult: ZsgDefaultValueGeneric[ 14 | Sample10ModelWithDefaultValue, 15 | ZsgTuple2[ZsgTuple2[ 16 | ZsgTuple2[ZsgTuple2[DefaultValue[String], DefaultValue[Int]], ZsgTuple2[DefaultValue[Int], DefaultValue[Long]]], 17 | ZsgTuple2[ZsgTuple2[DefaultValue[String], DefaultValue[List[SumII.Aux[Char]]]], ZsgTuple2[DefaultValue[Long], DefaultValue[ 18 | Option[Long] 19 | ]]] 20 | ], ZsgTuple2[DefaultValue[List[Long]], DefaultValue[String]]] 21 | ] = { 22 | ZsgDefaultValueGeneric.value { i => 23 | new ZsgTuple2( 24 | new ZsgTuple2( 25 | new ZsgTuple2( 26 | new ZsgTuple2(i.to(_.i1)(Option.empty), i.to(_.i2)(Option.empty)), 27 | new ZsgTuple2(i.to(_.i3)(Option.empty), i.to(_.i4)(Option.empty)) 28 | ), 29 | new ZsgTuple2( 30 | new ZsgTuple2( 31 | i.to(_.i5)(Some(Sample10ModelWithDefaultValue.apply$default$5)), 32 | i.to(_.i6)(Some(Sample10ModelWithDefaultValue.apply$default$6)) 33 | ), 34 | new ZsgTuple2(i.to(_.i7)(Option.empty), i.to(_.i8)(Some(Sample10ModelWithDefaultValue.apply$default$8))) 35 | ) 36 | ), 37 | new ZsgTuple2(i.to(_.i9)(Option.empty), i.to(_.i10)(Option.empty)) 38 | ) 39 | } 40 | } 41 | 42 | val macroResult = implicitly[ 43 | ZsgDefaultValueGeneric[ 44 | Sample10ModelWithDefaultValue, 45 | ZsgTuple2[ZsgTuple2[ 46 | ZsgTuple2[ZsgTuple2[DefaultValue[String], DefaultValue[Int]], ZsgTuple2[DefaultValue[Int], DefaultValue[Long]]], 47 | ZsgTuple2[ZsgTuple2[DefaultValue[String], DefaultValue[List[SumII.Aux[Char]]]], ZsgTuple2[DefaultValue[Long], DefaultValue[ 48 | Option[Long] 49 | ]]] 50 | ], ZsgTuple2[DefaultValue[List[Long]], DefaultValue[String]]] 51 | ] 52 | ] 53 | 54 | sameType( 55 | macroResult, 56 | genResult 57 | ) 58 | 59 | def main(arr: Array[String]): Unit = { 60 | val n: Option[List[SumII.Aux[Char]]] = macroResult.defaultValues.i1.i2.i1.i2.value 61 | val compare = Some(List.fill(5)("""interface zsg.sample03_macros_code_generation.SumII.Aux[char]""")) 62 | assert(n.map(_.map(_.toString)) == compare) 63 | println(n.to(List).flatten.mkString("\n")) 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /examples/src/main/scala-2/zsg/sample03_macros_code_generation/ZsgGenericCodeGenSample.scala: -------------------------------------------------------------------------------- 1 | package zsg.sample03_macros_code_generation 2 | 3 | import zsg._ 4 | import zsg.macros.single.ZsgGeneric 5 | 6 | object ZsgGenericCodeGenSample { 7 | 8 | def sameType[T](t1: T, t2: T): T = t1 9 | 10 | val genResult = { 11 | ZsgGeneric.GenericApply[Sample10].value { pro => 12 | ItemTag2( 13 | ItemTag2( 14 | ItemTag2(ItemTag2(pro.to(_.i1), pro.to(_.i2)), ItemTag2(pro.to(_.i3), pro.to(_.i4))), 15 | ItemTag2(ItemTag2(pro.to(_.i5), pro.to(_.i6)), ItemTag2(pro.to(_.i7), pro.to(_.i8))) 16 | ), 17 | ItemTag2(pro.to(_.i9), pro.to(_.i10)) 18 | ) 19 | } 20 | } 21 | 22 | sameType( 23 | implicitly[ZsgGeneric.Aux[Sample10, ItemTag2[ItemTag2[ 24 | ItemTag2[ItemTag2[PropertyTag[String], PropertyTag[Int]], ItemTag2[PropertyTag[Int], PropertyTag[Long]]], 25 | ItemTag2[ItemTag2[PropertyTag[String], PropertyTag[List[String]]], ItemTag2[PropertyTag[Long], PropertyTag[Option[Long]]]] 26 | ], ItemTag2[PropertyTag[List[Long]], PropertyTag[String]]]]], 27 | genResult 28 | ) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /examples/src/main/scala-21111/asuna/sample03_macros_code_generation/ZsgGetterGenericCodeGenSample.scala: -------------------------------------------------------------------------------- 1 | package zsg.sample03_macros_code_generation 2 | 3 | import zsg._ 4 | import zsg.macros.single.ZsgGetterGeneric 5 | 6 | object ZsgGetterGenericCodeGenSample { 7 | def sameType[T](t1: T, t2: T): T = t1 8 | 9 | val genResult: ZsgGetterGeneric[Sample10, ZTuple10[String, Int, Int, Long, String, List[String], Long, Option[Long], List[Long], String]] = 10 | new ZsgGetterGeneric[Sample10, ZTuple10[String, Int, Int, Long, String, List[String], Long, Option[Long], List[Long], String]] { 11 | override def getter(i: Sample10): ZTuple10[String, Int, Int, Long, String, List[String], Long, Option[Long], List[Long], String] = 12 | BuildContent.tuple10(i.i1, i.i2, i.i3, i.i4, i.i5, i.i6, i.i7, i.i8, i.i9, i.i10) 13 | } 14 | 15 | sameType( 16 | implicitly[ZsgGetterGeneric[Sample10, ZTuple10[String, Int, Int, Long, String, List[String], Long, Option[Long], List[Long], String]]], 17 | genResult 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /examples/src/main/scala-21111/asuna/sample03_macros_code_generation/ZsgLabelledGenericCodeGenSample.scala: -------------------------------------------------------------------------------- 1 | package zsg.sample03_macros_code_generation 2 | 3 | import zsg._ 4 | import zsg.macros.single.ZsgLabelledGeneric 5 | 6 | object ZsgLabelledGenericCodeGenSample { 7 | def sameType[T](t1: T, t2: T): T = t1 8 | 9 | val genResult: ZsgLabelledGeneric[Sample10, ZTuple10[String, String, String, String, String, String, String, String, String, String]] = 10 | ZsgLabelledGeneric.value(BuildContent.tuple10("i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8", "i9", "i10")) 11 | 12 | sameType(implicitly[ZsgLabelledGeneric[Sample10, ZTuple10[String, String, String, String, String, String, String, String, String, String]]], genResult) 13 | } 14 | -------------------------------------------------------------------------------- /examples/src/main/scala-21111/asuna/sample03_macros_code_generation/ZsgSealedClassGenericCodeGenSample.scala: -------------------------------------------------------------------------------- 1 | package zsg.sample03_macros_code_generation 2 | 3 | import zsg._ 4 | import zsg.macros.single.ZsgSealedClassGeneric 5 | 6 | object ZsgSealedClassGenericCodeGenSample { 7 | 8 | def sameType[T](t1: T, t2: T): T = t1 9 | 10 | val genResult: ZsgSealedClassGeneric[Foo, ZTuple4[Class[Bar1], Class[Bar2], Class[Bar3], Class[Bar4]]] = 11 | ZsgSealedClassGeneric.value(BuildContent.tuple4(classOf[Bar1], classOf[Bar2], classOf[Bar3], classOf[Bar4])) 12 | 13 | sameType(implicitly[ZsgSealedClassGeneric[Foo, ZTuple4[Class[Bar1], Class[Bar2], Class[Bar3], Class[Bar4]]]], genResult) 14 | 15 | } 16 | -------------------------------------------------------------------------------- /examples/src/main/scala-21111/asuna/sample03_macros_code_generation/ZsgSealedGenericCodeGenSample.scala: -------------------------------------------------------------------------------- 1 | package zsg.sample03_macros_code_generation 2 | 3 | import zsg._ 4 | import zsg.macros.single.{SealedTag, ZsgSealedGeneric} 5 | 6 | object ZsgSealedGenericCodeGenSample { 7 | 8 | def sameType[T](t1: T, t2: T): T = t1 9 | 10 | val genResult = implicitly[ZsgSealedGeneric.SealedGenericApply[Foo]].value(BuildContent.tuple4(SealedTag[Bar1], SealedTag[Bar2], SealedTag[Bar3], SealedTag[Bar4])) 11 | 12 | sameType(implicitly[ZsgSealedGeneric.Aux[Foo, ZTuple4[SealedTag[Bar1], SealedTag[Bar2], SealedTag[Bar3], SealedTag[Bar4]]]], genResult) 13 | 14 | } 15 | -------------------------------------------------------------------------------- /examples/src/main/scala-21111/asuna/sample03_macros_code_generation/ZsgSealedLabelledGenericCodeGenSample.scala: -------------------------------------------------------------------------------- 1 | package zsg.sample03_macros_code_generation 2 | 3 | import zsg._ 4 | import zsg.macros.single.ZsgSealedLabelledGeneric 5 | 6 | object ZsgSealedLabelledGenericCodeGenSample { 7 | 8 | def sameType[T](t1: T, t2: T): T = t1 9 | 10 | val genResult: ZsgSealedLabelledGeneric[Foo, ZTuple4[String, String, String, String]] = 11 | ZsgSealedLabelledGeneric.value(BuildContent.tuple4("Bar1", "Bar2", "Bar3", "Bar4")) 12 | 13 | sameType(implicitly[ZsgSealedLabelledGeneric[Foo, ZTuple4[String, String, String, String]]], genResult) 14 | 15 | } 16 | -------------------------------------------------------------------------------- /examples/src/main/scala-21111/asuna/sample03_macros_code_generation/ZsgSetterGenericCodeGenSample.scala: -------------------------------------------------------------------------------- 1 | package zsg.sample03_macros_code_generation 2 | 3 | import zsg._ 4 | import zsg.macros.single.ZsgSetterGeneric 5 | 6 | object ZsgSetterGenericCodeGenSample { 7 | def sameType[T](t1: T, t2: T): T = t1 8 | 9 | val genResult: ZsgSetterGeneric[Sample10, ZTuple10[String, Int, Int, Long, String, List[String], Long, Option[Long], List[Long], String]] = ZsgSetterGeneric.value { 10 | i => Sample10(i.i1, i.i2, i.i3, i.i4, i.i5, i.i6, i.i7, i.i8, i.i9, i.i10) 11 | } 12 | 13 | sameType(implicitly[ZsgSetterGeneric[Sample10, ZTuple10[String, Int, Int, Long, String, List[String], Long, Option[Long], List[Long], String]]], genResult) 14 | 15 | } 16 | -------------------------------------------------------------------------------- /examples/src/main/scala-21111/asuna/sample03_macros_code_generation/deficient/AsunaTupleApplyCodeGenSample.scala1111: -------------------------------------------------------------------------------- 1 | package asuna.sample03_macros_code_generation.deficient 2 | 3 | import asuna.macros.single.deficient.{AsunaTupleApply, DeficientProperty, ModelProperty} 4 | 5 | object AsunaTupleApplyCodeGenSample extends App { 6 | 7 | class Test1 8 | class Test2 9 | class Test3 { 10 | override def toString: String = "test3: String" 11 | } 12 | class Test4 13 | case class Model2[T](age: T, a3: Test3) 14 | 15 | case class Model1[T](name: String, age: T, a3: Test3, a4: Long) 16 | trait TupleModel { 17 | @ModelProperty 18 | def model: Model1[T] 19 | type T 20 | @DeficientProperty 21 | def tuple: Model2[T] 22 | } 23 | trait TupleModelImpl[T1] extends TupleModel { 24 | override type T = T1 25 | } 26 | 27 | def tupleModel[T](model1: Model1[T])(implicit i: AsunaTupleApply[Model1[T], TupleModelImpl[T]]): TupleModel = i.toTuple(model1) 28 | 29 | val model2 = tupleModel(Model1("123", 456, new Test3, 123)) 30 | println(model2.model) 31 | println(model2.tuple) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /examples/src/main/scala-21111/asuna/sample03_macros_code_generation/deficient/AsunaTupleGenericCodeGenSample.scala1111: -------------------------------------------------------------------------------- 1 | package asuna.sample03_macros_code_generation.deficient 2 | 3 | import asuna.{AppendTag, NodeTag1, NodeTag2, PropertyTag0, TupleTag, TupleTag1, TupleTag2} 4 | import asuna.macros.single.deficient.{AsunaTupleGeneric, DeficientProperty, ModelProperty} 5 | 6 | object AsunaTupleGenericCodeGenSample extends App { 7 | 8 | class Test1 9 | class Test2 10 | class Test3 { 11 | override def toString: String = "test3: String" 12 | } 13 | class Test4 14 | case class Model2[T](age: T, a3: Test3, a7: Test2) 15 | 16 | case class Model1[T](name: String, age: T, a3: Test3, a4: Long, a5: Test4, a6: Test1, a7: Test2, a8: Test3) 17 | trait TupleModel { 18 | @ModelProperty 19 | def model: Model1[T] 20 | type T 21 | @DeficientProperty 22 | def tuple: Model2[T] 23 | } 24 | 25 | class TupleModelImplicitApply[TraitType] { 26 | def model[T <: TupleTag](implicit i: AsunaTupleGeneric.Aux[TupleModel, T]): AppendTag[T] = i.tag 27 | } 28 | 29 | def tupleModel[TraitType]: TupleModelImplicitApply[TraitType] = new TupleModelImplicitApply[TraitType] 30 | 31 | val up = tupleModel[TupleModel].model 32 | 33 | up: AppendTag[ 34 | NodeTag2[NodeTag2[TupleTag2[PropertyTag0[String], PropertyTag0[Long]], TupleTag2[PropertyTag0[Test4], PropertyTag0[Test1]]], NodeTag1[TupleTag1[PropertyTag0[Test3]]]] 35 | ] 36 | 37 | } 38 | -------------------------------------------------------------------------------- /examples/src/main/scala-21111/asuna/sample03_macros_code_generation/deficient/AsunaTupleGetterGenericCodeGenSample.scala1111: -------------------------------------------------------------------------------- 1 | package asuna.sample03_macros_code_generation.deficient 2 | 3 | import asuna.{AsunaTuple1, AsunaTuple2} 4 | import asuna.macros.single.deficient.{AsunaTupleApply, AsunaTupleGetterGeneric, DeficientProperty, ModelProperty} 5 | 6 | object AsunaTupleGetterGenericCodeGenSample extends App { 7 | 8 | class Test1 9 | class Test2 10 | class Test3 { 11 | override def toString: String = "test3: String" 12 | } 13 | class Test4 { 14 | override def toString: String = "test4" 15 | } 16 | case class Model2[T](age: T, a3: Test3, a7: Test2) 17 | 18 | case class Model1[T](name: String, age: T, a3: Test3, a4: Long, a5: Test4, a6: Test1, a7: Test2, a8: Test3) 19 | trait TupleModel { 20 | @ModelProperty 21 | def model: Model1[T] 22 | type T 23 | @DeficientProperty 24 | def tuple: Model2[T] 25 | } 26 | trait TupleModelImpl[T1] extends TupleModel { 27 | override type T = T1 28 | } 29 | 30 | def model[T, P](implicit i: AsunaTupleGetterGeneric[T, P]): AsunaTupleGetterGeneric[T, P] = i 31 | 32 | val up = model[TupleModel, AsunaTuple2[AsunaTuple2[AsunaTuple2[String, Long], AsunaTuple2[Test4, Test1]], AsunaTuple1[AsunaTuple1[Test3]]]] 33 | 34 | val model = Model1(name = "name", age = 1234, a3 = new Test3, a4 = 2, a5 = new Test4, a6 = new Test1, a7 = new Test2, a8 = new Test3) 35 | def tupleModel[T](model1: Model1[T])(implicit i: AsunaTupleApply[Model1[T], TupleModelImpl[T]]): TupleModel = i.toTuple(model1) 36 | 37 | val p = tupleModel(model) 38 | 39 | val pp = up.getter(p) 40 | 41 | println(pp.i1.i1.i1) //name 42 | println(pp.i1.i2.i1) //test4 43 | 44 | } 45 | -------------------------------------------------------------------------------- /examples/src/main/scala-21111/asuna/sample03_macros_code_generation/deficient/AsunaTupleLabelledGenericCodeGenSample.scala1111: -------------------------------------------------------------------------------- 1 | package asuna.sample03_macros_code_generation.deficient 2 | 3 | import asuna.{AsunaTuple1, AsunaTuple2} 4 | import asuna.macros.single.deficient.{AsunaTupleLabelledGeneric, DeficientProperty, ModelProperty} 5 | 6 | object AsunaTupleLabelledGenericCodeGenSample extends App { 7 | 8 | class Test1 9 | class Test2 10 | class Test3 { 11 | override def toString: String = "test3: String" 12 | } 13 | class Test4 14 | case class Model2[T](age: T, a3: Test3, a7: Test2) 15 | 16 | case class Model1[T](name: String, age: T, a3: Test3, a4: Long, a5: Test4, a6: Test1, a7: Test2, a8: Test3) 17 | trait TupleModel { 18 | @ModelProperty 19 | def model: Model1[T] 20 | type T 21 | @DeficientProperty 22 | def tuple: Model2[T] 23 | } 24 | 25 | def model[T, P](implicit i: AsunaTupleLabelledGeneric[T, P]): P = i.names() 26 | 27 | val up = model[TupleModel, AsunaTuple2[AsunaTuple2[AsunaTuple2[String, String], AsunaTuple2[String, String]], AsunaTuple1[AsunaTuple1[String]]]] 28 | 29 | println(up.i1.i1.i1) //name 30 | println(up.i1.i2.i1) //a5 31 | 32 | } 33 | -------------------------------------------------------------------------------- /modules/benchmark/build.sbt: -------------------------------------------------------------------------------- 1 | CommonSettings.settings 2 | 3 | ZsgSettings.settings.dottyVersion 4 | 5 | libraryDependencies ++= Dependencies.circeDependencies(scalaVersion.value) 6 | libraryDependencies ++= Dependencies.upickleDependencies 7 | 8 | enablePlugins(JmhPlugin) 9 | -------------------------------------------------------------------------------- /modules/benchmark/src/main/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | # SLF4J's SimpleLogger configuration file 2 | # org.slf4j.simpleLogger.log.slick.jdbc.JdbcBackend.statement=debug 3 | # org.slf4j.simpleLogger.log.slick.jdbc.StatementInvoker.result=debug 4 | # org.slf4j.simpleLogger.log.slick.jdbc.JdbcBackend.parameter=debug -------------------------------------------------------------------------------- /modules/benchmark/src/main/scala/zsg/json/encoder/benchmark/JsonADTEncoderBenchmark.scala: -------------------------------------------------------------------------------- 1 | package zsg.json.encoder.benchmark 2 | 3 | import java.util.concurrent.TimeUnit 4 | 5 | import zsg.testkit.circe.ACirce 6 | import org.openjdk.jmh.annotations._ 7 | import zsg.json.model.adt.ADTBenchmarkModel 8 | 9 | @BenchmarkMode(Array(Mode.Throughput)) // 测试方法平均执行时间 10 | @OutputTimeUnit(TimeUnit.SECONDS) // 输出结果的时间粒度为微秒 11 | @State(Scope.Thread) // 每个测试线程一个实例 12 | class JsonADTEncoderBenchmark { 13 | 14 | import upickle.default.{macroRW, ReadWriter => RW} 15 | import upickle.default._ 16 | 17 | import zsg.json.model.adt.ADTs.ADT0 18 | import zsg.json.model.adt.Defaults._ 19 | import zsg.json.model.adt.Generic.ADT 20 | import zsg.json.model.adt.Hierarchy._ 21 | import zsg.json.model.adt.Recursive._ 22 | type Data = ADT[Seq[(Int, Int)], String, A, LL, ADTc, ADT0] 23 | 24 | import io.circe._ 25 | import io.circe.generic.semiauto._ 26 | 27 | val rawCirceEncoder: Encoder[Data] = { 28 | implicit lazy val _w2: Encoder[A] = deriveEncoder 29 | implicit lazy val _w3: Encoder[B] = deriveEncoder 30 | implicit lazy val _w4: Encoder[C] = deriveEncoder 31 | implicit lazy val _w5: Encoder[LL] = deriveEncoder 32 | implicit lazy val _w6: Encoder[Node] = deriveEncoder 33 | implicit lazy val _w7: Encoder[End.type] = deriveEncoder 34 | implicit lazy val _w8: Encoder[ADTc] = deriveEncoder 35 | implicit lazy val _w9: Encoder[ADT0] = deriveEncoder 36 | 37 | deriveEncoder 38 | } 39 | 40 | implicit val upickleRW: RW[Data] = { 41 | implicit lazy val _w2: RW[A] = macroRW 42 | implicit lazy val _w3: RW[B] = macroRW 43 | implicit lazy val _w4: RW[C] = macroRW 44 | implicit lazy val _w5: RW[LL] = macroRW 45 | implicit lazy val _w6: RW[Node] = macroRW 46 | implicit lazy val _w7: RW[End.type] = macroRW 47 | implicit lazy val _w8: RW[ADTc] = macroRW 48 | implicit lazy val _w9: RW[ADT0] = macroRW 49 | macroRW 50 | } 51 | 52 | object asunaEncoder { 53 | implicit val _w2: Encoder[A] = ACirce.encodeSealed 54 | implicit val _w3: Encoder[B] = ACirce.encodeCaseClass 55 | implicit val _w4: Encoder[C] = ACirce.encodeCaseClass 56 | implicit val _w5: Encoder[LL] = ACirce.encodeSealed 57 | implicit val _w6: Encoder[Node] = ACirce.encodeCaseClass 58 | implicit val _w7: Encoder[End.type] = ACirce.encodeCaseObject 59 | implicit val _w8: Encoder[ADTc] = ACirce.encodeCaseClass 60 | implicit val _w9: Encoder[ADT0] = ACirce.encodeCaseClass 61 | implicit val _wData: Encoder[Data] = ACirce.encodeCaseClass 62 | } 63 | 64 | @Benchmark 65 | def upickleTest = { 66 | import upickle.default._ 67 | write(ADTBenchmarkModel.benchmarkSampleData) 68 | } 69 | 70 | @Benchmark 71 | def zsgCirceTest = { 72 | asunaEncoder._wData(ADTBenchmarkModel.benchmarkSampleData).noSpaces 73 | } 74 | 75 | @Benchmark 76 | def vBaseCirceTest = { 77 | rawCirceEncoder(ADTBenchmarkModel.benchmarkSampleData).noSpaces 78 | } 79 | 80 | @TearDown 81 | def after: Unit = { 82 | val zsgCirceStr = asunaEncoder._wData(ADTBenchmarkModel.benchmarkSampleData).noSpaces 83 | val rawCirceStr = rawCirceEncoder(ADTBenchmarkModel.benchmarkSampleData).noSpaces 84 | val upickleStr = write(ADTBenchmarkModel.benchmarkSampleData)(upickleRW) 85 | println(s"zsg 结果: ${zsgCirceStr}") 86 | println(s"circe 结果: ${rawCirceStr}") 87 | println(s"upickle 结果: ${upickleStr}") 88 | println(s"zsgCirceStr == rawCirceStr: ${zsgCirceStr == rawCirceStr}") 89 | println(s"zsgCirceStr == upickleStr: ${zsgCirceStr == upickleStr}") 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /modules/benchmark/src/main/scala/zsg/json/encoder/benchmark/JsonEncoderBenchmark.scala: -------------------------------------------------------------------------------- 1 | package zsg.json.encoder.benchmark 2 | 3 | import java.util.concurrent.TimeUnit 4 | 5 | import org.openjdk.jmh.annotations._ 6 | import upickle.default.{ReadWriter => RW} 7 | import zsg.testkit.circe.ACirce 8 | import io.circe.Encoder 9 | import zsg.json.model.case_class.{Bar, BenchmarkModel, Foo} 10 | 11 | @BenchmarkMode(Array(Mode.Throughput)) // 测试方法平均执行时间 12 | @OutputTimeUnit(TimeUnit.SECONDS) // 输出结果的时间粒度为微秒 13 | @State(Scope.Thread) // 每个测试线程一个实例 14 | class JsonEncoderBenchmark { 15 | 16 | object uPickleRW { 17 | import upickle.default.macroRW 18 | implicit val barRW: RW[Bar] = macroRW 19 | implicit val fooRW: RW[Foo] = macroRW 20 | } 21 | 22 | object rawCirceEncoder { 23 | import io.circe.generic.semiauto._ 24 | implicit val barEncoder: Encoder.AsObject[Bar] = deriveEncoder 25 | implicit val fooEncoder: Encoder.AsObject[Foo] = deriveEncoder 26 | } 27 | 28 | object zsgEncoder { 29 | implicit val barEncoder: Encoder.AsObject[Bar] = ACirce.encodeCaseClass 30 | implicit val fooEncoder: Encoder.AsObject[Foo] = ACirce.encodeCaseClass 31 | } 32 | 33 | val model: Bar = BenchmarkModel.bar 34 | 35 | @Benchmark 36 | def uPickleEncode: String = { 37 | import upickle.default._ 38 | write(model)(uPickleRW.barRW) 39 | } 40 | 41 | @Benchmark 42 | def rawCirceEncode: String = { 43 | rawCirceEncoder.barEncoder(model).noSpaces 44 | } 45 | 46 | @Benchmark 47 | def zsgCirceEncode: String = { 48 | zsgEncoder.barEncoder(model).noSpaces 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /modules/benchmark/src/main/scala/zsg/json/model/adt/ADTBenchmarkModel.scala: -------------------------------------------------------------------------------- 1 | package zsg.json.model.adt 2 | 3 | object ADTBenchmarkModel { 4 | import ADTs.ADT0 5 | import Defaults._ 6 | import Generic.ADT 7 | import Hierarchy._ 8 | import Recursive._ 9 | type Data = ADT[Seq[(Int, Int)], String, A, LL, ADTc, ADT0] 10 | val benchmarkSampleData: Data = ADT( 11 | Vector((1, 2), (3, 4), (4, 5), (6, 7), (8, 9), (10, 11), (12, 13)), 12 | """ 13 | |I am cow, hear me moo 14 | |I weigh twice as much as you 15 | |And I look good on the barbecueeeee 16 | """.stripMargin, 17 | C("lol i am a noob", "haha you are a noob"): A, 18 | Node(-11, Node(-22, Node(-33, Node(-44, End)))): LL, 19 | ADTc(i = 1234567890, s = "i am a strange loop"), 20 | ADT0("1234") 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /modules/benchmark/src/main/scala/zsg/json/model/adt/ADTNodel.scala: -------------------------------------------------------------------------------- 1 | package zsg.json.model.adt 2 | 3 | object ADTs { 4 | case class ADT0(i1: String) 5 | } 6 | 7 | object Hierarchy { 8 | sealed trait A 9 | case class B(i: Int) extends A 10 | case class C(s1: String, s2: String) extends A 11 | 12 | sealed trait Z // new line 13 | case object AnZ extends Z // new line 14 | } 15 | 16 | object Generic { 17 | case class A[T](t: T) 18 | 19 | case class ADT[A, B, C, D, E, F](a: A, b: B, c: C, d: D, e: E, f: F) 20 | } 21 | 22 | object Recursive { 23 | sealed trait LL 24 | case object End extends LL 25 | case class Node(c: Int, next: LL) extends LL 26 | case class IntTree(value: Int, children: List[IntTree]) 27 | sealed trait SingleTree 28 | case class SingleNode(value: Int, children: List[SingleTree]) extends SingleTree 29 | } 30 | 31 | object Defaults { 32 | case class ADTa(i: Int = 0) 33 | case class ADTb(i: Int = 1, s: String) 34 | case class ADTc(i: Int = 2, s: String, t: (Double, Double) = (1, 2)) 35 | } 36 | -------------------------------------------------------------------------------- /modules/benchmark/src/main/scala/zsg/json/model/case_class/Bar.scala: -------------------------------------------------------------------------------- 1 | package zsg.json.model.case_class 2 | 3 | case class Bar(i1: Foo) 4 | -------------------------------------------------------------------------------- /modules/benchmark/src/main/scala/zsg/json/model/case_class/BenchmarkModel.scala: -------------------------------------------------------------------------------- 1 | package zsg.json.model.case_class 2 | 3 | object BenchmarkModel { 4 | val foo = Foo( 5 | i1 = 404, 6 | i2 = "init string", 7 | i3 = "init string", 8 | i4 = "init string", 9 | i5 = 2358, 10 | i6 = "init string", 11 | i7 = "init string", 12 | i8 = 36296, 13 | i9 = "init string", 14 | i10 = 2322, 15 | i11 = "init string", 16 | i12 = "2333" 17 | ) 18 | 19 | val bar = Bar(i1 = BenchmarkModel.foo) 20 | } 21 | -------------------------------------------------------------------------------- /modules/benchmark/src/main/scala/zsg/json/model/case_class/Foo.scala: -------------------------------------------------------------------------------- 1 | package zsg.json.model.case_class 2 | 3 | case class Foo( 4 | i1: Int, 5 | i2: String, 6 | i3: String, 7 | i4: String, 8 | i5: Int, 9 | i6: String, 10 | i7: String, 11 | i8: Long, 12 | i9: String, 13 | i10: Long, 14 | i11: String, 15 | i12: String 16 | ) 17 | -------------------------------------------------------------------------------- /modules/codegen/build.sbt: -------------------------------------------------------------------------------- 1 | ZsgSettings.settings.scala_2_12_And_2_13 2 | CommonSettings.settings 3 | enablePlugins(SbtTwirl) 4 | 5 | libraryDependencies += Dependencies.commonsIo 6 | libraryDependencies ++= Dependencies.zioTest 7 | -------------------------------------------------------------------------------- /modules/codegen/src/main/scala/zsg/codegen/DeleteTemp.scala: -------------------------------------------------------------------------------- 1 | package zsg.codegen 2 | 3 | import org.apache.commons.io.FileUtils 4 | 5 | object DeleteTemp { 6 | def main(i: Array[String]): Unit = { 7 | FileUtils.deleteDirectory(ZsgTestKitCodeGeneration.root2XDir.toFile) 8 | FileUtils.deleteDirectory(ZsgScalaTupleCodeGeneration.root2XDir.toFile) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/codegen/src/main/scala/zsg/codegen/StringUtil.scala: -------------------------------------------------------------------------------- 1 | package zsg.codegen 2 | 3 | import scala.io.Source 4 | import scala.util.Using 5 | 6 | object StringUtil { 7 | 8 | def trimLines(i: String): String = 9 | Using.resource(Source.fromString(i))(_.getLines().map(p => (p.trim, p)).filter(!_._1.isEmpty).map(_._2).mkString(System.lineSeparator)) 10 | 11 | } 12 | -------------------------------------------------------------------------------- /modules/codegen/src/main/scala/zsg/codegen/ZsgParameters.scala: -------------------------------------------------------------------------------- 1 | package zsg.codegen 2 | 3 | object ZsgParameters { 4 | val maxZTupleNum = 22 5 | val maxScala2TupleNum = 22 6 | } 7 | -------------------------------------------------------------------------------- /modules/codegen/src/main/scala/zsg/codegen/ZsgTestKitCodeGeneration.scala: -------------------------------------------------------------------------------- 1 | package zsg.codegen 2 | 3 | import java.io.PrintWriter 4 | import java.nio.file.{Files, Paths} 5 | 6 | import scala.util.Using 7 | 8 | object ZsgTestKitCodeGeneration { 9 | 10 | val root2XDir = Paths.get(".", "modules", "macros", "src", "test", "scala-2", "zsg", "macros", "case_class_test", "codegen") 11 | 12 | def main(i: Array[String]): Unit = { 13 | for (i <- List(1, 2, 3, 4, 68, 160)) yield { 14 | val filePath = root2XDir.resolve("CaseClassTest" + i + ".scala") 15 | Files.createDirectories(filePath.getParent) 16 | Using.resource(new PrintWriter(filePath.toFile, "utf-8")) { writer => 17 | val content = StringUtil.trimLines(zsg.codegen.testkit.txt.CaseClassTestKit(maxItem = i).body) 18 | writer.println(content) 19 | } 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /modules/codegen/src/main/scala/zsg/codegen/helper/TreeHelper.scala: -------------------------------------------------------------------------------- 1 | package zsg.codegen.helper 2 | 3 | import scala.io.Source 4 | import scala.util.Using 5 | 6 | // 在 scala macro 也引入这个文件的源码,可以独立一个文件夹,但不建立项目,以 source code 的形式引入 7 | sealed trait TreeAbs[+T] 8 | case class TreeContent[+T](content: List[TreeAbs[T]]) extends TreeAbs[T] { 9 | override def toString: String = { 10 | def genContent(t: TreeAbs[T]) = Using.resource(Source.fromString(t.toString))(_.getLines().to(List)) 11 | val contentStr = content.flatMap(genContent) 12 | s"TreeContent(\n${contentStr.map(s => s" $s").mkString("\n")}\n)" 13 | } 14 | } 15 | case class TreeLeaf[+T](leaf: T) extends TreeAbs[T] 16 | case object EmptyTree extends TreeAbs[Nothing] 17 | 18 | object TreeHelper { 19 | 20 | def fromSeq[T](seq: Seq[T], count: Int): TreeAbs[T] = groupedTree(seq.map(TreeLeaf(_)), count) 21 | 22 | private def groupedTree[T](tree: Seq[TreeAbs[T]], count: Int): TreeAbs[T] = { 23 | if (tree.size == 0) 24 | EmptyTree 25 | else if (tree.size == 1) 26 | tree.head 27 | else if (tree.size <= count) 28 | TreeContent(tree.to(List)) 29 | else { 30 | val grouped = tree.grouped(count).to(List) 31 | val seq = grouped.map(groupedTree(_, count)) 32 | groupedTree(seq, count) 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /modules/codegen/src/main/twirl/zsg/codegen/scalaTuple/ScalaTuple_Scala2_Implicit.scala.txt: -------------------------------------------------------------------------------- 1 | @(tagNum: Int) 2 | 3 | package zsg.scala.tuple 4 | 5 | import zsg.TypeFunction 6 | import zsg.TypeHList 7 | import zsg.Application 8 | import zsg.Context 9 | import zsg.Plus 10 | 11 | @tagSeq1(i: Int) = @{ 12 | val b = 1 to i 13 | b.map(s => s"v$s.application(context)") 14 | } 15 | 16 | trait TupleHelper { 17 | @for(i <- 2 to tagNum) { 18 | implicit def applicationScalaTupleImplicit@{i}[F <: TypeFunction @for(ii <- 1 to i) { , Boot@{ii}, Target@{ii} <: TypeHList }] 19 | (implicit @for(ii <- 1 to i) { @if(ii > 1) { , } v@{ii}: Application[F, Boot@{ii}, Target@{ii}] }): 20 | Application[F, Tuple@{i}[@for(ii <- 1 to i) { @if(ii > 1) { , } Boot@{ii} }], 21 | Tuple@{i}TypeHList[@for(ii <- 1 to i) { @if(ii > 1) { , } Target@{ii} }]] = 22 | new Application[F, Tuple@{i}[@for(ii <- 1 to i) { @if(ii > 1) { , } Boot@{ii} }], 23 | Tuple@{i}TypeHList[@for(ii <- 1 to i) { @if(ii > 1) { , } Target@{ii} }]] { 24 | override def application(context: Context[F]): F#H[Tuple@{i}TypeHList[@for(ii <- 1 to i) { @if(ii > 1) { , } Target@{ii} }]] = 25 | context.append(@zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString5(tagSeq1(i - 1)), v@{i}.application(context))(Tuple22Plus.tuple22Plus@{i - 1}) 26 | } 27 | } 28 | } 29 | 30 | object TupleHelper extends TupleHelper -------------------------------------------------------------------------------- /modules/codegen/src/main/twirl/zsg/codegen/scalaTuple/ScalaTuple_Scala2_TuplePlus.scala.txt: -------------------------------------------------------------------------------- 1 | @(tagNum: Int) 2 | 3 | package zsg.scala.tuple 4 | 5 | import zsg._ 6 | 7 | @tagSeq1(i: Int) = @{ 8 | val b = 1 to i 9 | b.map(s => s"I$s") 10 | } 11 | 12 | @tagSeq2(i: Int) = @{ 13 | val b = 1 to i 14 | b.map(s => s"I$s#Head") 15 | } 16 | 17 | @tagSeq3(i: Int) = @{ 18 | val b = 1 to i 19 | b.map(s => s"I$s#Tail") 20 | } 21 | 22 | @tagSeq4(i: Int) = @{ 23 | val b = 1 to i 24 | b.map(s => s"z._$s") 25 | } 26 | 27 | object Tuple22Plus { 28 | @for(i <- 1 to tagNum - 1) { 29 | def tuple22Plus@{i}[@for(ii <- 1 to i) { I@{ii} <: TypeHList, } Y <: TypeHList]: Plus[ 30 | @zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString1(tagSeq1(i)), Y, 31 | Tuple@{i + 1}TypeHList[@for(ii <- 1 to i) { I@{ii}, } Y] 32 | ] = new Plus[ 33 | @zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString1(tagSeq1(i)), Y, 34 | Tuple@{i + 1}TypeHList[@for(ii <- 1 to i) { I@{ii}, } Y] 35 | ] { 36 | override def takeHead(z: Tuple@{i + 1}[@for(ii <- 1 to i) { I@{ii}#Head, } Y#Head]): @zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString2(tagSeq2(i)) = 37 | @zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString3(tagSeq4(i)) 38 | override def takeTail(z: Tuple@{i + 1}[@for(ii <- 1 to i) { I@{ii}#Head, } Y#Head]): Y#Head = z._@{i + 1} 39 | override def plus(x: @zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString2(tagSeq2(i)), y: Y#Head): Tuple@{i + 1}[@for(ii <- 1 to i) { I@{ii}#Head, } Y#Head] = 40 | Tuple@{i + 1}(@zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString4(i, "x").mkString(", "), y) 41 | override def tail: Plus[@zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString1(tagSeq3(i)), Y#Tail, Tuple@{i + 1}TypeHList[@for(ii <- 1 to i) { I@{ii}#Tail, } Y#Tail]] = 42 | tuple22Plus@{i}[@for(ii <- 1 to i) { I@{ii}#Tail, } Y#Tail] 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /modules/codegen/src/main/twirl/zsg/codegen/scalaTuple/ScalaTuple_Scala2_TypeHList.scala.txt: -------------------------------------------------------------------------------- 1 | @(tagNum: Int) 2 | 3 | package zsg.scala.tuple 4 | 5 | import zsg.TypeHList 6 | 7 | @for(i <- 1 to tagNum) { 8 | class Tuple@{i}TypeHList[@for(ii <- 1 to i) { @if(ii > 1) { , } I@{ii} <: TypeHList }] extends TypeHList { 9 | override type Head = Tuple@{i}[@for(ii <- 1 to i) { @if(ii > 1) { , } I@{ii}#Head }] 10 | override type Tail = Tuple@{i}TypeHList[@for(ii <- 1 to i) { @if(ii > 1) { , } I@{ii}#Tail }] 11 | } 12 | } -------------------------------------------------------------------------------- /modules/codegen/src/main/twirl/zsg/codegen/tuple/TagMerge.scala.txt: -------------------------------------------------------------------------------- 1 | @(tagNum: Int) 2 | 3 | package zsg 4 | 5 | @for(i <- 2 to tagNum) { 6 | 7 | class TagMerge@{i}[I1 @for(ii <- 2 to i) { , I@{ii} }] { 8 | type Target 9 | } 10 | object TagMerge@{i} extends TagMerge@{i}ImplicitImpl { 11 | type Aux[@for(ii <- 1 to i) { I@{ii}, } T] = TagMerge@{i}[I1 @for(ii <- 2 to i) { , I@{ii} }] { type Target = T } 12 | val tagMergeAny = new TagMerge@{i}[Any @for(ii <- 2 to i) { , Any }] 13 | def tagMerge@{i}[@for(ii <- 1 to i) { I@{ii}, } Target]: Aux[@for(ii <- 1 to i) { I@{ii}, } Target] = tagMergeAny.asInstanceOf[Aux[@for(ii <- 1 to i) { I@{ii}, } Target]] 14 | implicit def merge@{i}Implicit2[@for(ii <- 1 to i) { S@{ii}, } @for(ii <- 1 to i) { T@{ii}, } Target1, Target2](implicit 15 | i1: Aux[@for(ii <- 1 to i) { S@{ii}, } Target1], 16 | i2: Aux[@for(ii <- 1 to i) { T@{ii}, } Target2] 17 | ): Aux[@for(ii <- 1 to i) { ItemTag2[S@{ii}, T@{ii}], } ItemTag2[Target1, Target2]] = tagMerge@{i} 18 | } 19 | 20 | trait TagMerge@{i}ImplicitImpl { 21 | implicit def merge@{i}Implicit1[I1 @for(ii <- 2 to i) { , I@{ii} }]: TagMerge@{i}.Aux[I1 @for(ii <- 2 to i) { , I@{ii} }, TagMerge@{i}[I1 @for(ii <- 2 to i) { , I@{ii} }]] = TagMerge@{i}.tagMerge@{i} 22 | } 23 | } -------------------------------------------------------------------------------- /modules/codegen/src/main/twirl/zsg/codegen/tuple/TypeHListX.scala.txt: -------------------------------------------------------------------------------- 1 | @(maxItem: Int) 2 | 3 | package zsg 4 | 5 | object TypeAlias { 6 | type TypeHList1[T1] = TypeHList { type Head = T1 } 7 | @for(i <- 2 to maxItem) { 8 | @zsg.codegen.ZsgCoreCodeGeneration.typeHListXGen1(i) 9 | } 10 | } -------------------------------------------------------------------------------- /modules/codegen/src/main/twirl/zsg/scala3Codegen/scalaTuple/ScalaTuple_Scala3_Implicit.scala.txt: -------------------------------------------------------------------------------- 1 | @(tagNum: Int) 2 | 3 | package zsg.scala.tuple 4 | 5 | import zsg.TypeHList 6 | import zsg.Application 7 | import zsg.Context 8 | import zsg.Plus 9 | 10 | @tagSeq1(i: Int) = @{ 11 | val b = 1 to i 12 | b.map(s => s"v$s.application(context)") 13 | } 14 | 15 | trait TupleHelper extends TupleHelper23 { 16 | @for(i <- 2 to tagNum) { 17 | given[T <: Context @for(ii <- 1 to i) { , Boot@{ii}, Target@{ii} <: TypeHList }](using 18 | @for(ii <- 1 to i) { @if(ii > 1) { , } v@{ii}: Application[T, Boot@{ii}, Target@{ii}] }): 19 | Application[T, Tuple@{i}[@for(ii <- 1 to i) { @if(ii > 1) { , } Boot@{ii} }], 20 | Tuple@{i}TypeHList[@for(ii <- 1 to i) { @if(ii > 1) { , } Target@{ii} }]] = 21 | context => context.append(@zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString5(tagSeq1(i - 1)), v@{i}.application(context))(Tuple22Plus.tuple22Plus@{i - 1}) 22 | } 23 | } 24 | 25 | object TupleHelper extends TupleHelper -------------------------------------------------------------------------------- /modules/codegen/src/main/twirl/zsg/scala3Codegen/scalaTuple/ScalaTuple_Scala3_TuplePlus.scala.txt: -------------------------------------------------------------------------------- 1 | @(tagNum: Int) 2 | 3 | package zsg.scala.tuple 4 | 5 | import zsg._ 6 | 7 | @tagSeq1(i: Int) = @{ 8 | val b = 1 to i 9 | b.map(s => s"I$s") 10 | } 11 | 12 | @tagSeq2(i: Int) = @{ 13 | val b = 1 to i 14 | b.map(s => s"TypeHead[I$s]") 15 | } 16 | 17 | @tagSeq3(i: Int) = @{ 18 | val b = 1 to i 19 | b.map(s => s"TypeTail[I$s]") 20 | } 21 | 22 | @tagSeq4(i: Int) = @{ 23 | val b = 1 to i 24 | b.map(s => s"z._$s") 25 | } 26 | 27 | @tagSeq5(i: Int) = @{ 28 | val b = 1 to i 29 | b.map(s => s"Any") 30 | } 31 | 32 | object Tuple22Plus { 33 | @for(i <- 1 to tagNum - 1) { 34 | def tuple22Plus@{i}[@for(ii <- 1 to i) { I@{ii} <: TypeHList, } Y <: TypeHList]: Plus[ 35 | @zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString1(tagSeq1(i)), Y, 36 | Tuple@{i + 1}TypeHList[@for(ii <- 1 to i) { I@{ii}, } Y] 37 | ] = new Plus[ 38 | @zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString1(tagSeq1(i)), Y, 39 | Tuple@{i + 1}TypeHList[@for(ii <- 1 to i) { I@{ii}, } Y] 40 | ] { 41 | override def takeHead(u: TypeHead[Tuple@{i + 1}TypeHList[@for(ii <- 1 to i) { I@{ii}, } Y]]): TypeHead[@zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString1(tagSeq1(i))] = { 42 | val z = u.asInstanceOf[Tuple@{i + 1}[@for(ii <- 1 to i + 1) { @if(ii > 1) { , } _ }]] 43 | @zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString3(tagSeq4(i)) .asInstanceOf[TypeHead[@{zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString1(tagSeq1(i))}]] 44 | } 45 | override def takeTail(u: TypeHead[Tuple@{i + 1}TypeHList[@for(ii <- 1 to i) { I@{ii}, } Y]]): TypeHead[Y] = { 46 | val z = u.asInstanceOf[Tuple@{i + 1}[@for(ii <- 1 to i) { TypeHead[I@{i}], } TypeHead[Y]]] 47 | z._@{i + 1} 48 | } 49 | override def plus(u: TypeHead[@zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString1(tagSeq1(i))], y: TypeHead[Y]): TypeHead[Tuple@{i + 1}TypeHList[@for(ii <- 1 to i) { I@{ii}, } Y]] = { 50 | val x = u.asInstanceOf[@zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString2(tagSeq5(i))] 51 | Tuple@{i + 1}(@zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString4(i, "x").mkString(", "), y).asInstanceOf[TypeHead[Tuple@{i + 1}TypeHList[@for(ii <- 1 to i) { I@{ii}, } Y]]] 52 | } 53 | override def tail: Plus[TypeTail[@zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString1(tagSeq1(i))], TypeTail[Y], TypeTail[Tuple@{i + 1}TypeHList[@for(ii <- 1 to i) { I@{ii}, } Y]]] = 54 | tuple22Plus@{i}[@for(ii <- 1 to i) { TypeTail[I@{ii}], } TypeTail[Y]].asInstanceOf[Plus[ 55 | TypeTail[@zsg.codegen.ZsgScalaTupleCodeGeneration.genHListString1(tagSeq1(i))], TypeTail[Y], 56 | TypeTail[Tuple@{i + 1}TypeHList[@for(ii <- 1 to i) { I@{ii}, } Y]] 57 | ]] 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /modules/codegen/src/main/twirl/zsg/scala3Codegen/scalaTuple/ScalaTuple_Scala3_TypeHList.scala.txt: -------------------------------------------------------------------------------- 1 | @(tagNum: Int) 2 | 3 | package zsg.scala.tuple 4 | 5 | import zsg.TypeHList 6 | import zsg.TypePositive 7 | import zsg.TypeZero 8 | 9 | type Tuple1TypeHList[I1 <: TypeHList] <: TypeHList = I1 match { 10 | case TypePositive[head1, tail1] => TypePositive[Tuple1[head1], Tuple1TypeHList[tail1]] 11 | case TypeZero => TypeZero 12 | } 13 | 14 | @for(i <- 2 to tagNum) { 15 | type Tuple@{i}TypeHList[@for(ii <- 1 to i) { @if(ii > 1) { , } I@{ii} <: TypeHList }] <: TypeHList = (@for(ii <- 1 to i) { @if(ii > 1) { , } I@{ii} }) match { 16 | case (@for(ii <- 1 to i) { @if(ii > 1) { , } TypePositive[head@{ii}, tail@{ii}] }) => 17 | TypePositive[Tuple@{i}[@for(ii <- 1 to i) { @if(ii > 1) { , } head@{ii} }], Tuple@{i}TypeHList[@for(ii <- 1 to i) { @if(ii > 1) { , } tail@{ii} }]] 18 | case (@for(ii <- 1 to i) { @if(ii > 1) { , } TypeZero }) => TypeZero 19 | } 20 | } -------------------------------------------------------------------------------- /modules/codegen/src/main/twirl/zsg/scala3Codegen/tuple/TagMerge.scala.txt1111: -------------------------------------------------------------------------------- 1 | @(tagNum: Int) 2 | 3 | package zsg 4 | 5 | @for(i <- 2 to tagNum) { 6 | 7 | class TagMerge@{i}[I1 @for(ii <- 2 to i) { , I@{ii} }] { 8 | type Target 9 | } 10 | object TagMerge@{i} extends TagMerge@{i}ImplicitImpl { 11 | type Aux[@for(ii <- 1 to i) { I@{ii}, } T] = TagMerge@{i}[I1 @for(ii <- 2 to i) { , I@{ii} }] { type Target = T } 12 | val tagMergeAny = new TagMerge@{i}[Any @for(ii <- 2 to i) { , Any }] 13 | def tagMerge@{i}[@for(ii <- 1 to i) { I@{ii}, } Target]: Aux[@for(ii <- 1 to i) { I@{ii}, } Target] = tagMergeAny.asInstanceOf[Aux[@for(ii <- 1 to i) { I@{ii}, } Target]] 14 | implicit def merge@{i}Implicit2[@for(ii <- 1 to i) { S@{ii}, } @for(ii <- 1 to i) { T@{ii}, } Target1, Target2](implicit 15 | i1: Aux[@for(ii <- 1 to i) { S@{ii}, } Target1], 16 | i2: Aux[@for(ii <- 1 to i) { T@{ii}, } Target2] 17 | ): Aux[@for(ii <- 1 to i) { ItemTag2[S@{ii}, T@{ii}], } ItemTag2[Target1, Target2]] = tagMerge@{i} 18 | } 19 | 20 | trait TagMerge@{i}ImplicitImpl { 21 | implicit def merge@{i}Implicit1[I1 @for(ii <- 2 to i) { , I@{ii} }]: TagMerge@{i}.Aux[I1 @for(ii <- 2 to i) { , I@{ii} }, TagMerge@{i}[I1 @for(ii <- 2 to i) { , I@{ii} }]] = TagMerge@{i}.tagMerge@{i} 22 | } 23 | } -------------------------------------------------------------------------------- /modules/codegen/src/main/twirl/zsg/scala3Codegen/tuple/TypeHListX.scala.txt: -------------------------------------------------------------------------------- 1 | @(maxItem: Int) 2 | 3 | package zsg 4 | 5 | package inner { 6 | object innerTypeAlias { 7 | import zsg._ 8 | type TakeTail1[T <: TypeHList] <: TypeHList = T match { 9 | case TypePositive[head, tail] => tail 10 | } 11 | @for(i <- 2 to maxItem - 1) { 12 | type TakeTail@{i}[T <: TypeHList] <: TypeHList = TakeTail@{i - 1}[T] match { 13 | case TypePositive[head, tail] => tail 14 | } 15 | } 16 | } 17 | } 18 | 19 | type TakeHead1[T <: TypeHList] = T match { 20 | case TypePositive[head, tail] => head 21 | } 22 | @for(i <- 2 to maxItem) { 23 | type TakeHead@{i}[T <: TypeHList] = inner.innerTypeAlias.TakeTail@{i - 1}[T] match { 24 | case TypePositive[head, tail] => head 25 | } 26 | } 27 | @for(i <- 2 to maxItem) { 28 | @zsg.codegen.ZsgCoreCodeGeneration.scala3TypeHListXGen(i) 29 | } -------------------------------------------------------------------------------- /modules/core/build.sbt: -------------------------------------------------------------------------------- 1 | ZsgSettings.settings.dottyVersion 2 | CommonSettings.settings 3 | 4 | // libraryDependencies ++= Dependencies.zioTest 5 | -------------------------------------------------------------------------------- /modules/core/src/codegen/scala-2/zsg/TypeHListX.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | object TypeAlias { 3 | type TypeHList1[T1] = TypeHList { type Head = T1 } 4 | type TypeHList2[T1, T2] = TypeHList { type Head = T1; type Tail = TypeHList1[T2] } 5 | type TypeHList3[T1, T2, T3] = TypeHList { type Head = T1; type Tail = TypeHList2[T2, T3] } 6 | type TypeHList4[T1, T2, T3, T4] = TypeHList { type Head = T1; type Tail = TypeHList3[T2, T3, T4] } 7 | type TypeHList5[T1, T2, T3, T4, T5] = TypeHList { type Head = T1; type Tail = TypeHList4[T2, T3, T4, T5] } 8 | type TypeHList6[T1, T2, T3, T4, T5, T6] = TypeHList { type Head = T1; type Tail = TypeHList5[T2, T3, T4, T5, T6] } 9 | type TypeHList7[T1, T2, T3, T4, T5, T6, T7] = TypeHList { type Head = T1; type Tail = TypeHList6[T2, T3, T4, T5, T6, T7] } 10 | type TypeHList8[T1, T2, T3, T4, T5, T6, T7, T8] = TypeHList { type Head = T1; type Tail = TypeHList7[T2, T3, T4, T5, T6, T7, T8] } 11 | type TypeHList9[T1, T2, T3, T4, T5, T6, T7, T8, T9] = TypeHList { type Head = T1; type Tail = TypeHList8[T2, T3, T4, T5, T6, T7, T8, T9] } 12 | type TypeHList10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] = TypeHList { type Head = T1; type Tail = TypeHList9[T2, T3, T4, T5, T6, T7, T8, T9, T10] } 13 | type TypeHList11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] = TypeHList { type Head = T1; type Tail = TypeHList10[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] } 14 | type TypeHList12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] = TypeHList { type Head = T1; type Tail = TypeHList11[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] } 15 | type TypeHList13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] = TypeHList { type Head = T1; type Tail = TypeHList12[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] } 16 | type TypeHList14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] = TypeHList { type Head = T1; type Tail = TypeHList13[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] } 17 | type TypeHList15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] = TypeHList { type Head = T1; type Tail = TypeHList14[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] } 18 | type TypeHList16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] = TypeHList { type Head = T1; type Tail = TypeHList15[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] } 19 | type TypeHList17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] = TypeHList { type Head = T1; type Tail = TypeHList16[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] } 20 | type TypeHList18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] = TypeHList { type Head = T1; type Tail = TypeHList17[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] } 21 | type TypeHList19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] = TypeHList { type Head = T1; type Tail = TypeHList18[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] } 22 | type TypeHList20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] = TypeHList { type Head = T1; type Tail = TypeHList19[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] } 23 | type TypeHList21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] = TypeHList { type Head = T1; type Tail = TypeHList20[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] } 24 | type TypeHList22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] = TypeHList { type Head = T1; type Tail = TypeHList21[T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] } 25 | } 26 | -------------------------------------------------------------------------------- /modules/core/src/main/scala-2/zsg/Application.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | abstract class Application[F <: TypeFunction, Boot, Target <: TypeHList] { 4 | def application(context: Context[F]): F#H[Target] 5 | } 6 | 7 | object Application { 8 | implicit def applicationImplicit2[F <: TypeFunction, Boot1, Boot2, Target1 <: TypeHList, Target2 <: TypeHList](implicit 9 | i1: Application[F, Boot1, Target1], 10 | i2: Application[F, Boot2, Target2] 11 | ): Application[F, ItemTag2[Boot1, Boot2], Item2TypeHList[Target1, Target2]] = 12 | new Application[F, ItemTag2[Boot1, Boot2], Item2TypeHList[Target1, Target2]] { 13 | def application(context: Context[F]): F#H[Item2TypeHList[Target1, Target2]] = 14 | context.append(i1.application(context), i2.application(context))(Plus.item2Plus) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /modules/core/src/main/scala-2/zsg/Context.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | abstract class Context[F <: TypeFunction] { 4 | def append[X <: TypeHList, Y <: TypeHList, Z <: TypeHList](x: F#H[X], y: F#H[Y])(plus: Plus[X, Y, Z]): F#H[Z] 5 | } 6 | -------------------------------------------------------------------------------- /modules/core/src/main/scala-2/zsg/Item2TypeHList.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | class Item2TypeHList[I1 <: TypeHList, I2 <: TypeHList] extends TypeHList { 4 | override type Head = ZsgTuple2[I1#Head, I2#Head] 5 | override type Tail = Item2TypeHList[I1#Tail, I2#Tail] 6 | } 7 | -------------------------------------------------------------------------------- /modules/core/src/main/scala-2/zsg/Plus.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | abstract class Plus[X <: TypeHList, Y <: TypeHList, Z <: TypeHList] { 4 | def takeHead(z: Z#Head): X#Head 5 | def takeTail(z: Z#Head): Y#Head 6 | def plus(x: X#Head, y: Y#Head): Z#Head 7 | def tail: Plus[X#Tail, Y#Tail, Z#Tail] 8 | } 9 | 10 | object Plus { 11 | private def item2PlusImpl[X <: TypeHList, Y <: TypeHList]: Plus[X, Y, Item2TypeHList[X, Y]] = new Plus[X, Y, Item2TypeHList[X, Y]] { 12 | override def takeHead(z: ZsgTuple2[X#Head, Y#Head]): X#Head = z.i1 13 | override def takeTail(z: ZsgTuple2[X#Head, Y#Head]): Y#Head = z.i2 14 | override def plus(x: X#Head, y: Y#Head): ZsgTuple2[X#Head, Y#Head] = new ZsgTuple2(i1 = x, i2 = y) 15 | override def tail: Plus[X#Tail, Y#Tail, Item2TypeHList[X#Tail, Y#Tail]] = item2Plus 16 | } 17 | private val item2PlusAny = item2PlusImpl[TypeHList, TypeHList] 18 | def item2Plus[X <: TypeHList, Y <: TypeHList]: Plus[X, Y, Item2TypeHList[X, Y]] = 19 | item2PlusAny.asInstanceOf[Plus[X, Y, Item2TypeHList[X, Y]]] 20 | } 21 | -------------------------------------------------------------------------------- /modules/core/src/main/scala-2/zsg/TypeFunction.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | trait TypeFunction { 4 | type H[_ <: TypeHList] 5 | } 6 | -------------------------------------------------------------------------------- /modules/core/src/main/scala-2/zsg/TypeHList.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | trait TypeHList { 4 | type Head 5 | type Tail <: TypeHList 6 | } 7 | -------------------------------------------------------------------------------- /modules/core/src/main/scala-3/zsg/Application.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | trait Application[N <: Context, B, I <: TypeHList] { 4 | def application(context: N): context.T[I] 5 | } 6 | 7 | object Application { 8 | inline given [N <: Context, B1, B2, I1 <: TypeHList, I2 <: TypeHList](using 9 | a1: Application[N, B1, I1], 10 | a2: Application[N, B2, I2] 11 | ): Application[N, ItemTag2[B1, B2], Item2TypeHList[I1, I2]] = context => 12 | context.append(a1.application(context), a2.application(context))(Plus.item2Plus) 13 | } 14 | -------------------------------------------------------------------------------- /modules/core/src/main/scala-3/zsg/Context.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | trait Context { 4 | type T[_ <: TypeHList] 5 | def append[X <: TypeHList, Y <: TypeHList, Z <: TypeHList](x: T[X], y: T[Y])(plus: Plus[X, Y, Z]): T[Z] 6 | } 7 | -------------------------------------------------------------------------------- /modules/core/src/main/scala-3/zsg/Item2TypeHList.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | type Item2TypeHList[T1 <: TypeHList, T2 <: TypeHList] <: TypeHList = (T1, T2) match { 4 | case (TypePositive[head1, tail1], TypePositive[head2, tail2]) => TypePositive[ZsgTuple2[head1, head2], Item2TypeHList[tail1, tail2]] 5 | case (TypeZero, TypeZero) => TypeZero 6 | } 7 | -------------------------------------------------------------------------------- /modules/core/src/main/scala-3/zsg/Plus.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | trait Plus[X <: TypeHList, Y <: TypeHList, Z <: TypeHList] { 4 | def takeHead(z: TypeHead[Z]): TypeHead[X] 5 | def takeTail(z: TypeHead[Z]): TypeHead[Y] 6 | def plus(x: TypeHead[X], y: TypeHead[Y]): TypeHead[Z] 7 | def tail: Plus[TypeTail[X], TypeTail[Y], TypeTail[Z]] 8 | } 9 | 10 | object Plus { 11 | def plusInstanceImpl[X <: TypeHList, Y <: TypeHList]: Plus[X, Y, Item2TypeHList[X, Y]] = new Plus[X, Y, Item2TypeHList[X, Y]] { 12 | override def takeHead(z: TypeHead[Item2TypeHList[X, Y]]): TypeHead[X] = z.asInstanceOf[ZsgTuple2[TypeHead[X], TypeHead[Y]]].i1 13 | override def takeTail(z: TypeHead[Item2TypeHList[X, Y]]): TypeHead[Y] = z.asInstanceOf[ZsgTuple2[TypeHead[X], TypeHead[Y]]].i2 14 | override def plus(x: TypeHead[X], y: TypeHead[Y]): TypeHead[Item2TypeHList[X, Y]] = 15 | new ZsgTuple2(x, y).asInstanceOf[TypeHead[Item2TypeHList[X, Y]]] 16 | override def tail: Plus[TypeTail[X], TypeTail[Y], TypeTail[Item2TypeHList[X, Y]]] = 17 | plusInstanceAny.asInstanceOf[Plus[TypeTail[X], TypeTail[Y], TypeTail[Item2TypeHList[X, Y]]]] 18 | } 19 | 20 | val plusInstanceAny = plusInstanceImpl[TypeHList, TypeHList] 21 | 22 | inline def item2Plus[X <: TypeHList, Y <: TypeHList]: Plus[X, Y, Item2TypeHList[X, Y]] = 23 | plusInstanceAny.asInstanceOf[Plus[X, Y, Item2TypeHList[X, Y]]] 24 | } 25 | -------------------------------------------------------------------------------- /modules/core/src/main/scala-3/zsg/TypeHList.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | trait TypeHList 4 | class TypeZero extends TypeHList 5 | class TypePositive[Head, Tail <: TypeHList] extends TypeHList 6 | 7 | type TypeHead[T <: TypeHList] = T match { 8 | case TypePositive[head, tail] => head 9 | } 10 | type TypeTail[T <: TypeHList] <: TypeHList = T match { 11 | case TypePositive[head, tail] => tail 12 | } 13 | -------------------------------------------------------------------------------- /modules/core/src/main/scala/zsg/ItemTag2.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | class ItemTag2[I1, I2] 4 | 5 | object ItemTag2 { 6 | val itemTagAny = new ItemTag2[Any, Any] 7 | def apply[I1, I2]: ItemTag2[I1, I2] = itemTagAny.asInstanceOf[ItemTag2[I1, I2]] 8 | def apply[I1, I2](i1: I1, i2: I2): ItemTag2[I1, I2] = apply[I1, I2] 9 | } 10 | -------------------------------------------------------------------------------- /modules/core/src/main/scala/zsg/PlaceHolder.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.utils 2 | 3 | class PlaceHolder 4 | 5 | object PlaceHolder { 6 | val value: PlaceHolder = new PlaceHolder 7 | } 8 | -------------------------------------------------------------------------------- /modules/core/src/main/scala/zsg/PropertyTag.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | trait PropertyTag[T] 3 | 4 | object PropertyTag { 5 | val value: PropertyTag[Any] = new PropertyTag[Any] {} 6 | def apply[T]: PropertyTag[T] = value.asInstanceOf[PropertyTag[T]] 7 | } 8 | -------------------------------------------------------------------------------- /modules/core/src/main/scala/zsg/ZsgTuple2.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | final class ZsgTuple2[X1, X2](final val i1: X1, final val i2: X2) 3 | -------------------------------------------------------------------------------- /modules/core/version.sbt: -------------------------------------------------------------------------------- 1 | CommonSettings.projectVersionSetting 2 | name := "zsg-core" 3 | -------------------------------------------------------------------------------- /modules/macros/build.sbt: -------------------------------------------------------------------------------- 1 | ZsgSettings.settings.dottyVersion 2 | CommonSettings.settings 3 | 4 | libraryDependencies ++= Dependencies.scalaReflect(scalaVersion.value) 5 | libraryDependencies += Dependencies.slf4j % Test 6 | libraryDependencies += Dependencies.scalaCollectionCompat 7 | 8 | libraryDependencies += Dependencies.commonsCodec % Compile 9 | 10 | libraryDependencies ++= Dependencies.zioTest 11 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2.11-2.12/zsg/macros/ByNameImplicit.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros 2 | 3 | import scala.reflect.macros.blackbox 4 | 5 | import scala.language.experimental.macros 6 | 7 | abstract class ByNameImplicit[T] { 8 | def value: T 9 | } 10 | 11 | object ByNameImplicit { 12 | implicit def implicitFetch[T]: ByNameImplicit[T] = macro ByNameImplicitHelper.Impl.fetch[T] 13 | 14 | private object ByNameImplicitHelper { 15 | 16 | class Impl(val c: blackbox.Context) { 17 | import c.universe._ 18 | 19 | def fetch[T: c.WeakTypeTag]: c.Expr[ByNameImplicit[T]] = { 20 | val byNameImplicit = weakTypeOf[ByNameImplicit[T]].resultType 21 | val t = weakTypeOf[T].resultType 22 | c.Expr[ByNameImplicit[T]] { 23 | q"""new ${byNameImplicit} { @inline override def value: ${t} = implicitly[${t}] }""" 24 | } 25 | } 26 | } 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2.11-2.12/zsg/macros/utils/GenericColumnName.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.utils 2 | 3 | import scala.language.experimental.macros 4 | 5 | class GenericColumnName[N <: String](val value: String) extends AnyVal 6 | 7 | object GenericColumnName { 8 | 9 | implicit def nImplicit[N <: String]: GenericColumnName[N] = macro GenericColumnNameMacroApply.MacroImpl.generic[N] 10 | 11 | private object GenericColumnNameMacroApply { 12 | class MacroImpl(val c: scala.reflect.macros.blackbox.Context) { 13 | import c.universe._ 14 | def generic[N <: String: c.WeakTypeTag]: c.Expr[GenericColumnName[N]] = { 15 | try { 16 | val n = weakTypeOf[N] 17 | val ConstantType(Constant(name: String)) = n 18 | c.Expr[GenericColumnName[N]] { 19 | q"""new _root_.zsg.macros.utils.GenericColumnName[${n}](${Literal(Constant(name.trim))})""" 20 | } 21 | } catch { 22 | case e: Exception => 23 | e.printStackTrace() 24 | throw e 25 | } 26 | } 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2.11-2.12/zsg/macros/utils/MacroMethods.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.utils 2 | 3 | trait MacroMethods { 4 | val c: scala.reflect.macros.blackbox.Context 5 | import c.universe._ 6 | 7 | def namedParam(name: TermName, value: Tree): Tree = AssignOrNamedArg(Ident(name), value) 8 | def vectorAppendAll[T](vector1: Vector[T], vector2: Vector[T]): Vector[T] = vector1 ++: vector2 9 | def vectorAppend[T](vector1: Vector[T], item: T): Vector[T] = vector1 ++: Vector(item) 10 | } 11 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2.13/zsg/macros/ByNameImplicit.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros 2 | 3 | abstract class ByNameImplicit[T] { 4 | def value: T 5 | } 6 | 7 | object ByNameImplicit { 8 | implicit def implicitFetch[T](implicit byNameValue: => T): ByNameImplicit[T] = new ByNameImplicit[T] { 9 | override def value: T = byNameValue 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2.13/zsg/macros/utils/GenericColumnName.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.utils 2 | 3 | class GenericColumnName[N <: String](val value: String) extends AnyVal 4 | 5 | object GenericColumnName { 6 | implicit def nameImplicit[N <: String](implicit name: ValueOf[N]): GenericColumnName[N] = new GenericColumnName[N](name.value) 7 | } 8 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2.13/zsg/macros/utils/MacroMethods.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.utils 2 | 3 | trait MacroMethods { 4 | val c: scala.reflect.macros.blackbox.Context 5 | import c.universe._ 6 | 7 | def namedParam(name: TermName, value: Tree): Tree = NamedArg(Ident(name), value) 8 | def vectorAppendAll[T](vector1: Vector[T], vector2: Vector[T]): Vector[T] = vector1.appendedAll(vector2) 9 | def vectorAppend[T](vector1: Vector[T], item: T): Vector[T] = vector1.appended(item) 10 | } 11 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/AllScalaMacroMethods.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros 2 | 3 | trait AllScalaMacroMethods { 4 | val c: scala.reflect.macros.blackbox.Context 5 | import c.universe._ 6 | 7 | case class CompanionWithSymbol(companionSymbol: Option[Symbol], companionTree: Tree) 8 | 9 | def companionOfSymbol(symbol: Symbol): CompanionWithSymbol = 10 | symbol.companion match { 11 | case NoSymbol => CompanionWithSymbol(Option.empty, q"""${symbol.name.toTermName}""") 12 | case s if s.isStatic => CompanionWithSymbol(Option(s), q"""${s}""") 13 | case s if !s.isStatic => CompanionWithSymbol(Option(s), q"""${symbol.name.toTermName}""") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/multiply/RootTable.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.multiply 2 | 3 | import scala.annotation.StaticAnnotation 4 | 5 | case class RootTable(order: Int = RootTable.defaultRootTableOrder) extends StaticAnnotation 6 | 7 | object RootTable { 8 | val defaultRootTableOrder: Int = 0 9 | } 10 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/multiply/ZsgMultiplyRepGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.multiply 2 | 3 | import zsg.macros.ZsgParameters 4 | import zsg.macros.multiply.utils.PropertyOverrideHelper 5 | 6 | import scala.language.experimental.macros 7 | 8 | trait ZsgMultiplyRepGeneric[Table, Model, Rep] { 9 | def rep(table: Table): Rep 10 | } 11 | 12 | object ZsgMultiplyRepGeneric { 13 | def value[Table, Model, Rep](i: Table => Rep): ZsgMultiplyRepGeneric[Table, Model, Rep] = 14 | new ZsgMultiplyRepGeneric[Table, Model, Rep] { 15 | override def rep(table: Table): Rep = i(table) 16 | } 17 | implicit def macroImpl[Table, Model, Rep]: ZsgMultiplyRepGeneric[Table, Model, Rep] = 18 | macro ZsgMultiplyRepGenericApply.MacroImpl.generic[Table, Model, Rep] 19 | } 20 | 21 | object ZsgMultiplyRepGenericApply { 22 | 23 | class MacroImpl(override val c: scala.reflect.macros.blackbox.Context) extends PropertyOverrideHelper { 24 | self => 25 | 26 | import c.universe._ 27 | 28 | def generic[Table: c.WeakTypeTag, Model: c.WeakTypeTag, M: c.WeakTypeTag]: c.Expr[ZsgMultiplyRepGeneric[Table, Model, M]] = { 29 | try { 30 | val t = weakTypeOf[Table] 31 | val m = weakTypeOf[Model] 32 | val tType = t.resultType 33 | val mType = m.resultType 34 | 35 | val props = mType.members.toList 36 | .filter { s => s.isTerm && s.asTerm.isVal && s.asTerm.isCaseAccessor } 37 | .map(s => (s.name, s)) 38 | .collect { case (TermName(n), s) => 39 | val proName = n.trim 40 | proName 41 | } 42 | .reverse 43 | 44 | val tableFields = tType.members.toList 45 | .filter(s => s.isTerm) 46 | .map(s => (s.name, s)) 47 | .collect { case (TermName(n), s) => 48 | val proName = n.trim 49 | (List(proName), s, s.typeSignatureIn(tType)) 50 | } 51 | .reverse 52 | 53 | val tableProps = tableFields.map(s => tablePropsGen(s._1, s._2, s._3, Map.empty)).foldLeft(Map.empty[String, List[String]]) { 54 | (start, path) => start ++ path 55 | } 56 | 57 | def tableProperty(s: String): Tree = { 58 | tableProps 59 | .get(s) 60 | .map((fieldName) => fieldName.foldLeft(q"""table""": Tree) { (start, termName) => q"""${start}.${TermName(termName)}""" }) 61 | .getOrElse( 62 | q"""_root_.zsg.macros.utils.PlaceHolder.value""" 63 | ) 64 | } 65 | 66 | val proTypeTag = props.map(s => tableProperty(s)) 67 | 68 | def nameTagGen(tree: List[Tree]): Tree = if (tree.length == 1) q"""{ table => ..$tree }""" 69 | else { 70 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).toList 71 | nameTagGen(groupedTree.map(s => if (s.size > 1) q"""new _root_.zsg.ZsgTuple2(..$s)""" else q"""..$s""")) 72 | } 73 | 74 | c.Expr[ZsgMultiplyRepGeneric[Table, Model, M]] { 75 | q"""_root_.zsg.macros.multiply.ZsgMultiplyRepGeneric.value(${nameTagGen(proTypeTag)})""" 76 | } 77 | 78 | } catch { 79 | case e: Exception => 80 | e.printStackTrace 81 | throw e 82 | } 83 | } 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/multiply/utils/PropertyOverrideHelper.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.multiply.utils 2 | 3 | import zsg.macros.multiply.RootTable 4 | 5 | import scala.annotation.meta.getter 6 | import scala.language.experimental.macros 7 | 8 | trait PropertyOverrideHelper { 9 | 10 | val c: scala.reflect.macros.blackbox.Context 11 | 12 | import c.universe._ 13 | 14 | def tablePropsGen(keys: List[String], field: Symbol, rootType: Type, mapping: Map[String, List[String]]): Map[String, List[String]] = { 15 | val newRootType = field.typeSignatureIn(rootType) 16 | val TermName(n1) = field.name 17 | val fieldName = n1.trim 18 | val newMapping1 = mapping + ((fieldName, keys)) 19 | 20 | val orderOpt = field.annotations 21 | .map(_.tree) 22 | .collect { 23 | case q"""new ${classDef}(${Literal(Constant(num: Int))})""" if classDef.tpe.<:<(weakTypeOf[RootTable @getter]) => 24 | num 25 | case q"""new ${classDef}(${_})""" if classDef.tpe.<:<(weakTypeOf[RootTable @getter]) => 26 | RootTable.apply$default$1 27 | } 28 | .headOption 29 | 30 | orderOpt match { 31 | case Some(_) => 32 | val newMapList = newRootType.members.toList 33 | .filter(_.isTerm) 34 | .map(s => (s.name, s)) 35 | .collect { case (TermName(n), s) => 36 | val proName = n.trim 37 | (proName, s) 38 | } 39 | .reverse 40 | .map { case (r, s) => tablePropsGen(keys ::: r :: Nil, s, s.typeSignatureIn(newRootType), Map.empty) } 41 | newMapList.foldLeft(newMapping1) { (start, m) => start ++ m } 42 | 43 | case _ => newMapping1 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/ZsgDefaultValueGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | import zsg.macros.single.utils.TypeHelper 4 | import zsg.macros.{AllScalaMacroMethods, ZsgParameters} 5 | import zsg.macros.utils.MacroMethods 6 | 7 | import scala.language.experimental.macros 8 | import scala.collection.compat._ 9 | 10 | trait DefaultValue[T] { 11 | def value: Option[T] 12 | } 13 | 14 | object DefaultValue { 15 | def model[Model]: DefaultValueApply[Model] = new DefaultValueApply[Model] 16 | 17 | class DefaultValueApply[Model] { 18 | def to[R](m: Model => R)(o: => Option[R]): DefaultValue[R] = { 19 | new DefaultValue[R] { 20 | override def value: Option[R] = o 21 | } 22 | } 23 | } 24 | 25 | object DefaultValueApply { 26 | val value = new DefaultValueApply[Any] 27 | def apply[T] = value.asInstanceOf[DefaultValueApply[T]] 28 | } 29 | 30 | } 31 | 32 | abstract class ZsgDefaultValueGeneric[H, DefaultValueType] { 33 | def defaultValues: DefaultValueType 34 | } 35 | 36 | class ZsgDefaultValue { 37 | type ModelType[M] = ZsgDefaultValueGenericImpl1[M] 38 | class ZsgDefaultValueGenericImpl1[Model] { 39 | type GenericType[G] = ZsgDefaultValueGeneric[Model, G] 40 | } 41 | } 42 | 43 | object ZsgDefaultValueGeneric { 44 | 45 | @inline def value[T, Model](t: DefaultValue.DefaultValueApply[Model] => T): ZsgDefaultValueGeneric[Model, T] = 46 | new ZsgDefaultValueGeneric[Model, T] { 47 | override def defaultValues: T = t(DefaultValue.DefaultValueApply[Model]) 48 | } 49 | 50 | implicit def macroImpl[H, II]: ZsgDefaultValueGeneric[H, II] = macro ZsgDefaultValueGenericMacroApply.MacroImpl.generic[H, II] 51 | 52 | } 53 | 54 | object ZsgDefaultValueGenericMacroApply { 55 | 56 | class MacroImpl(override val c: scala.reflect.macros.blackbox.Context) extends MacroMethods with AllScalaMacroMethods with TypeHelper { 57 | self => 58 | 59 | import c.universe._ 60 | 61 | def generic[H: c.WeakTypeTag, M: c.WeakTypeTag]: c.Expr[ZsgDefaultValueGeneric[H, M]] = { 62 | try { 63 | val rSym = symbolOf[H] 64 | 65 | val h = c.weakTypeOf[H] 66 | val hType = h.resultType 67 | 68 | def props = caseClassMembersByType(hType) 69 | 70 | def defaultValue = props.map(i => q"""item.to(_.${i.fieldTermName})(Option.empty)""") 71 | val b = companionOfSymbol(rSym) 72 | 73 | val proTypeTag = b.companionSymbol 74 | .map { s => 75 | val apply = s.typeSignature.decl(TermName("apply")).asMethod 76 | apply.paramLists.head.map(_.asTerm).zipWithIndex.map { case (p, i) => 77 | if (!p.isParamWithDefault) q"""item.to(_.${p.name})(Option.empty)""" 78 | else { 79 | val getterName = TermName("apply$default$" + (i + 1)) 80 | q"""item.to(_.${p.name})(Some(${b.companionTree}.$getterName))""" 81 | } 82 | } 83 | } 84 | .getOrElse(defaultValue) 85 | 86 | val nameTag = proTypeTag 87 | def nameTagGen(tree: List[Tree]): Tree = if (tree.length == 1) q"""..${tree}""" 88 | else { 89 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).to(List) 90 | nameTagGen(groupedTree.map(s => if (s.size > 1) q"""new _root_.zsg.ZsgTuple2(..${s})""" else q"""..$s""")) 91 | } 92 | 93 | c.Expr[ZsgDefaultValueGeneric[H, M]] { 94 | q"""_root_.zsg.macros.single.ZsgDefaultValueGeneric.value(item => ${nameTagGen(nameTag)})""" 95 | } 96 | 97 | } catch { 98 | case e: Exception => 99 | e.printStackTrace 100 | throw e 101 | } 102 | } 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/ZsgGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | import zsg.macros.ZsgParameters 4 | import zsg.macros.single.utils.TypeHelper 5 | 6 | import scala.language.experimental.macros 7 | import scala.collection.compat._ 8 | 9 | trait ZsgGeneric[H] { 10 | type WT 11 | def tag: WT 12 | } 13 | 14 | object ZsgGeneric { 15 | 16 | type Aux[H, II] = ZsgGeneric[H] { type WT = II } 17 | 18 | class GenericApply[M] { 19 | def generic[WW](implicit i: ZsgGeneric.Aux[M, WW]): ZsgGeneric.Aux[M, WW] = i 20 | def value[K](i: PropertyApply[M] => K): ZsgGeneric.Aux[M, K] = 21 | new ZsgGeneric[M] { 22 | override type WT = K 23 | override def tag: WT = i(PropertyApply[M]) 24 | } 25 | } 26 | 27 | object GenericApply { 28 | val value = new GenericApply[Any] 29 | def apply[T]: ZsgGeneric.GenericApply[T] = value.asInstanceOf[GenericApply[T]] 30 | implicit def init[M]: ZsgGeneric.GenericApply[M] = GenericApply[M] 31 | } 32 | 33 | implicit def macroImpl[H, II](implicit prop: ZsgGeneric.GenericApply[H]): ZsgGeneric.Aux[H, II] = 34 | macro ZsgGenericMacroApply.MacroImpl.generic[H, II] 35 | 36 | } 37 | 38 | object ZsgGenericMacroApply { 39 | 40 | class MacroImpl(override val c: scala.reflect.macros.whitebox.Context) extends TypeHelper { 41 | self => 42 | 43 | import c.universe._ 44 | 45 | def generic[H: c.WeakTypeTag, II: c.WeakTypeTag](prop: c.Expr[ZsgGeneric.GenericApply[H]]): c.Expr[ZsgGeneric.Aux[H, II]] = { 46 | try { 47 | val h = weakTypeOf[H] 48 | val hType = h.resultType 49 | 50 | val props = caseClassMembersByType(hType) 51 | 52 | val proTypeTag = props.map(s => q"""item.to(_.${s.fieldTermName})""") 53 | 54 | def typeTagGen(tree: List[Tree]): Tree = if (tree.length == 1) q"""..${tree}""" 55 | else { 56 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).to(List) 57 | typeTagGen(groupedTree.map(s => if (s.size > 1) q"""_root_.zsg.ItemTag2(..$s)""" else q"""..$s""")) 58 | } 59 | 60 | c.Expr[ZsgGeneric.Aux[H, II]] { 61 | q"""$prop.value(item => ${typeTagGen(proTypeTag)})""" 62 | } 63 | 64 | } catch { 65 | case e: Exception => 66 | e.printStackTrace 67 | throw e 68 | } 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/ZsgGetterGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | import zsg.macros.ZsgParameters 4 | import zsg.macros.single.utils.TypeHelper 5 | 6 | import scala.language.experimental.macros 7 | import scala.collection.compat._ 8 | 9 | trait ZsgGetterGeneric[H, GenericType] { 10 | def getter(model: H): GenericType 11 | } 12 | 13 | object ZsgGetterGeneric { 14 | @inline def value[H, GenericType](i: H => GenericType): ZsgGetterGeneric[H, GenericType] = 15 | new ZsgGetterGeneric[H, GenericType] { 16 | override def getter(model: H): GenericType = i(model) 17 | } 18 | implicit def macroImpl[H, M]: ZsgGetterGeneric[H, M] = macro ZsgGetterGenericMacroApply.MacroImpl.generic[H, M] 19 | 20 | } 21 | 22 | object ZsgGetterGenericMacroApply { 23 | 24 | class MacroImpl(override val c: scala.reflect.macros.blackbox.Context) extends TypeHelper { 25 | self => 26 | 27 | import c.universe._ 28 | 29 | def generic[H: c.WeakTypeTag, M: c.WeakTypeTag]: c.Expr[ZsgGetterGeneric[H, M]] = { 30 | try { 31 | val h = c.weakTypeOf[H] 32 | val hType = h.resultType 33 | 34 | val props = caseClassMembersByType(hType) 35 | 36 | val nameTag = props.map { name => q"""s.${name.fieldTermName}""" } 37 | def nameTagGen(tree: List[Tree]): Tree = if (tree.length == 1) q"""(s: ${h}) => { ..${tree} }""" 38 | else { 39 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).to(List) 40 | nameTagGen(groupedTree.map(s => if (s.size > 1) q"""new _root_.zsg.ZsgTuple2(..${s})""" else q"""..$s""")) 41 | } 42 | 43 | c.Expr[ZsgGetterGeneric[H, M]] { 44 | q"""_root_.zsg.macros.single.ZsgGetterGeneric.value(${nameTagGen(nameTag)})""" 45 | } 46 | 47 | } catch { 48 | case e: Exception => 49 | e.printStackTrace 50 | throw e 51 | } 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/ZsgLabelledGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | import zsg.macros.ZsgParameters 4 | import zsg.macros.single.utils.TypeHelper 5 | 6 | import scala.language.experimental.macros 7 | import scala.collection.compat._ 8 | 9 | trait ZsgLabelledGeneric[H, NameType] { 10 | def names: NameType 11 | } 12 | 13 | object ZsgLabelledGeneric { 14 | @inline def value[T, Model](name: T): ZsgLabelledGeneric[Model, T] = 15 | new ZsgLabelledGeneric[Model, T] { 16 | override def names: T = name 17 | } 18 | 19 | implicit def macroImpl[H, II]: ZsgLabelledGeneric[H, II] = macro ZsgLabelledGenericMacroApply.MacroImpl.generic[H, II] 20 | 21 | } 22 | 23 | object ZsgLabelledGenericMacroApply { 24 | 25 | class MacroImpl(override val c: scala.reflect.macros.blackbox.Context) extends TypeHelper { 26 | self => 27 | 28 | import c.universe._ 29 | 30 | def generic[H: c.WeakTypeTag, M: c.WeakTypeTag]: c.Expr[ZsgLabelledGeneric[H, M]] = { 31 | try { 32 | val h = c.weakTypeOf[H] 33 | val hType = h.resultType 34 | 35 | val props = caseClassMembersByType(hType) 36 | 37 | val nameTag = props.map { name => q"""${Literal(Constant(name.fieldName))}""" } 38 | def nameTagGen(tree: List[Tree]): Tree = if (tree.length == 1) q"""..${tree}""" 39 | else { 40 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).to(List) 41 | nameTagGen(groupedTree.map(s => if (s.size > 1) q"""new _root_.zsg.ZsgTuple2(..${s})""" else q"""..$s""")) 42 | } 43 | 44 | c.Expr[ZsgLabelledGeneric[H, M]] { 45 | q"""_root_.zsg.macros.single.ZsgLabelledGeneric.value(${nameTagGen(nameTag)})""" 46 | } 47 | 48 | } catch { 49 | case e: Exception => 50 | e.printStackTrace 51 | throw e 52 | } 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/ZsgLabelledTypeGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | import zsg.macros.ZsgParameters 4 | import zsg.macros.single.utils.TypeHelper 5 | 6 | import scala.language.experimental.macros 7 | import scala.collection.compat._ 8 | 9 | trait ZsgLabelledTypeGeneric[CaseClass] { 10 | type WT 11 | def tag: WT 12 | } 13 | 14 | object ZsgLabelledTypeGeneric { 15 | type Aux[C, W] = ZsgLabelledTypeGeneric[C] { type WT = W } 16 | 17 | val value: ZsgLabelledTypeGeneric.Aux[Any, Any] = new ZsgLabelledTypeGeneric[Any] { 18 | override type WT = Any 19 | override def tag: Any = null 20 | } 21 | def apply[Model, T]: ZsgLabelledTypeGeneric.Aux[Model, T] = value.asInstanceOf[ZsgLabelledTypeGeneric.Aux[Model, T]] 22 | class ZsgLabeledTypeGenericApply[Model] { 23 | def model[T](tag: => T): ZsgLabelledTypeGeneric.Aux[Model, T] = apply[Model, T] 24 | } 25 | object ZsgLabeledTypeGenericApply { 26 | val value: ZsgLabeledTypeGenericApply[Any] = new ZsgLabeledTypeGenericApply[Any] 27 | def apply[T] = value.asInstanceOf[ZsgLabeledTypeGenericApply[T]] 28 | } 29 | 30 | def apply[M]: ZsgLabeledTypeGenericApply[M] = ZsgLabeledTypeGenericApply[M] 31 | 32 | implicit def lImplicit[CaseClass, T]: ZsgLabelledTypeGeneric.Aux[CaseClass, T] = 33 | macro ZsgLabelledTypeGenericMacroApply.MacroImpl.generic[CaseClass, T] 34 | } 35 | 36 | object ZsgLabelledTypeGenericMacroApply { 37 | 38 | class MacroImpl(override val c: scala.reflect.macros.whitebox.Context) extends TypeHelper { 39 | self => 40 | 41 | import c.universe._ 42 | 43 | def generic[CaseClass: c.WeakTypeTag, T: c.WeakTypeTag]: c.Expr[ZsgLabelledTypeGeneric.Aux[CaseClass, T]] = { 44 | try { 45 | val caseClass = weakTypeOf[CaseClass] 46 | val caseClassType = caseClass.resultType 47 | 48 | val props = caseClassMembersByType(caseClassType) 49 | 50 | // model.${TermName(s.fieldName)}.type 51 | val proTypeTag = props.map(s => q"""_root_.zsg.macros.single.ColumnName[${c.internal.constantType(Constant(s.fieldName))}]""") 52 | 53 | case class bb(i1: Int) 54 | def typeTagGen(tree: List[Tree]): Tree = if (tree.length == 1) q"""..${tree}""" 55 | else { 56 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).to(List) 57 | typeTagGen(groupedTree.map(s => if (s.size > 1) q"""_root_.zsg.ItemTag2(..$s)""" else q"""..$s""")) 58 | } 59 | 60 | c.Expr[ZsgLabelledTypeGeneric.Aux[CaseClass, T]] { 61 | q"""_root_.zsg.macros.single.ZsgLabelledTypeGeneric[${caseClass}].model(${typeTagGen(proTypeTag)})""" 62 | } 63 | 64 | } catch { 65 | case e: Exception => 66 | e.printStackTrace 67 | throw e 68 | } 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/ZsgSealedClassGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | import zsg.macros.ZsgParameters 4 | import zsg.macros.single.utils.SealedHelper 5 | 6 | import scala.language.experimental.macros 7 | import scala.collection.compat._ 8 | 9 | trait ZsgSealedClassGeneric[H, NameType] { 10 | def names: NameType 11 | } 12 | 13 | object ZsgSealedClassGeneric { 14 | 15 | def value[T, Model](name: T): ZsgSealedClassGeneric[Model, T] = 16 | new ZsgSealedClassGeneric[Model, T] { 17 | override def names: T = name 18 | } 19 | 20 | implicit def macroImpl[H, II]: ZsgSealedClassGeneric[H, II] = macro ZsgSealedClassGenericMacroApply.MacroImpl1.generic[H, II] 21 | 22 | } 23 | 24 | object ZsgSealedClassGenericMacroApply { 25 | 26 | class MacroImpl1(override val c: scala.reflect.macros.blackbox.Context) extends SealedHelper { 27 | self => 28 | 29 | import c.universe._ 30 | 31 | def generic[H: c.WeakTypeTag, M: c.WeakTypeTag]: c.Expr[ZsgSealedClassGeneric[H, M]] = { 32 | try { 33 | val h = c.weakTypeOf[H] 34 | val hType = h.resultType 35 | 36 | val props = fleshedOutSubtypes(hType).to(List) 37 | 38 | val nameTag = props.map { subType => q"""classOf[${subType}]""" } 39 | def nameTagGen(tree: List[Tree]): Tree = if (tree.length == 1) q"""..${tree}""" 40 | else { 41 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).to(List) 42 | nameTagGen(groupedTree.map(s => if (s.size > 1) q"""new _root_.zsg.ZsgTuple2(..${s})""" else q"""..$s""")) 43 | } 44 | 45 | c.Expr[ZsgSealedClassGeneric[H, M]] { 46 | q"""_root_.zsg.macros.single.ZsgSealedClassGeneric.value(${nameTagGen(nameTag)})""" 47 | } 48 | 49 | } catch { 50 | case e: Exception => 51 | e.printStackTrace 52 | throw e 53 | } 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/ZsgSealedGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | import zsg.macros.ZsgParameters 4 | import zsg.macros.single.utils.SealedHelper 5 | 6 | import scala.annotation.tailrec 7 | import scala.language.experimental.macros 8 | import scala.collection.compat._ 9 | 10 | trait ZsgSealedGeneric[H] { 11 | type Sealed 12 | def tag: Sealed 13 | } 14 | 15 | class SealedTag[T] 16 | 17 | object SealedTag { 18 | def apply[T]: SealedTag[T] = new SealedTag[T] 19 | } 20 | 21 | object ZsgSealedGeneric { 22 | 23 | class SealedGenericApply[I] { 24 | def value[M](value1: => M): ZsgSealedGeneric.Aux[I, M] = 25 | new ZsgSealedGeneric[I] { 26 | override type Sealed = M 27 | override def tag: M = value1 28 | } 29 | } 30 | object SealedGenericApply { 31 | val value: SealedGenericApply[Any] = new SealedGenericApply[Any] 32 | def apply[T]: SealedGenericApply[T] = value.asInstanceOf[SealedGenericApply[T]] 33 | } 34 | 35 | type Aux[H, II] = ZsgSealedGeneric[H] { type Sealed = II } 36 | 37 | implicit def macroImpl[H, II]: ZsgSealedGeneric.Aux[H, II] = macro ZsgSealedGenericMacroApply.MacroImpl1.generic[H, II] 38 | 39 | } 40 | 41 | object ZsgSealedGenericMacroApply { 42 | 43 | class MacroImpl1(override val c: scala.reflect.macros.whitebox.Context) extends SealedHelper { 44 | self => 45 | 46 | import c.universe._ 47 | 48 | def generic[H: WeakTypeTag, M: WeakTypeTag]: c.Expr[ZsgSealedGeneric.Aux[H, M]] = { 49 | try { 50 | val h = weakTypeOf[H] 51 | 52 | val props = fleshedOutSubtypes(h).to(List) 53 | 54 | val proTypeTag = props.map(s => q"""_root_.zsg.macros.single.SealedTag[${s}]""") 55 | 56 | @tailrec 57 | def typeTagGen(tree: List[Tree]): Tree = if (tree.length == 1) q"""..$tree""" 58 | else { 59 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).to(List) 60 | typeTagGen(groupedTree.map(s => if (s.size > 1) q"""_root_.zsg.ItemTag2(..$s)""" else q"""..$s""")) 61 | } 62 | 63 | c.Expr[ZsgSealedGeneric.Aux[H, M]] { 64 | q"""_root_.zsg.macros.single.ZsgSealedGeneric.SealedGenericApply[$h].value(${typeTagGen(proTypeTag)})""" 65 | } 66 | 67 | } catch { 68 | case e: Exception => 69 | e.printStackTrace 70 | throw e 71 | } 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/ZsgSealedLabelledGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | import zsg.macros.ZsgParameters 4 | import zsg.macros.single.utils.SealedHelper 5 | 6 | import scala.language.experimental.macros 7 | import scala.collection.compat._ 8 | 9 | trait ZsgSealedLabelledGeneric[H, NameType] { 10 | def names: NameType 11 | } 12 | 13 | object ZsgSealedLabelledGeneric { 14 | 15 | def value[T, Model](name: T): ZsgSealedLabelledGeneric[Model, T] = 16 | new ZsgSealedLabelledGeneric[Model, T] { 17 | override def names: T = name 18 | } 19 | 20 | implicit def macroImpl[H, II]: ZsgSealedLabelledGeneric[H, II] = macro ZsgSealedLabelledGenericMacroApply.MacroImpl1.generic[H, II] 21 | 22 | } 23 | 24 | object ZsgSealedLabelledGenericMacroApply { 25 | 26 | class MacroImpl1(override val c: scala.reflect.macros.blackbox.Context) extends SealedHelper { 27 | self => 28 | 29 | import c.universe._ 30 | 31 | def generic[H: c.WeakTypeTag, M: c.WeakTypeTag]: c.Expr[ZsgSealedLabelledGeneric[H, M]] = { 32 | try { 33 | val h = c.weakTypeOf[H] 34 | val hType = h.resultType 35 | 36 | val props = fleshedOutSubtypes(hType).to(List) 37 | 38 | val nameTag = props.map { subType => q"""${Literal(Constant(subType.typeSymbol.name.toString))}""" } 39 | def nameTagGen(tree: List[Tree]): Tree = if (tree.length == 1) q"""..${tree}""" 40 | else { 41 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).to(List) 42 | nameTagGen(groupedTree.map(s => if (s.size > 1) q"""new _root_.zsg.ZsgTuple2(..${s})""" else q"""..$s""")) 43 | } 44 | 45 | c.Expr[ZsgSealedLabelledGeneric[H, M]] { 46 | q"""_root_.zsg.macros.single.ZsgSealedLabelledGeneric.value(${nameTagGen(nameTag)})""" 47 | } 48 | 49 | } catch { 50 | case e: Exception => 51 | e.printStackTrace 52 | throw e 53 | } 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/ZsgSetterGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | import zsg.macros.single.utils.TypeHelper 4 | import zsg.macros.{AllScalaMacroMethods, ZsgParameters} 5 | import zsg.macros.utils.MacroMethods 6 | 7 | import scala.annotation.tailrec 8 | import scala.language.experimental.macros 9 | import scala.collection.compat._ 10 | 11 | trait ZsgSetterGeneric[H, GenericType] { 12 | def setter(gen: GenericType): H 13 | } 14 | 15 | object ZsgSetterGeneric { 16 | 17 | def value[Model, GenericType](i: GenericType => Model): ZsgSetterGeneric[Model, GenericType] = 18 | new ZsgSetterGeneric[Model, GenericType] { 19 | override def setter(gen: GenericType): Model = i(gen) 20 | } 21 | 22 | implicit def macroImpl[H, M]: ZsgSetterGeneric[H, M] = macro ZsgSetterGenericMacroApply.MacroImpl.generic[H, M] 23 | 24 | } 25 | 26 | object ZsgSetterGenericMacroApply { 27 | 28 | class MacroImpl(override val c: scala.reflect.macros.blackbox.Context) extends MacroMethods with AllScalaMacroMethods with TypeHelper { 29 | self => 30 | 31 | import c.universe._ 32 | 33 | def generic[H: c.WeakTypeTag, M: c.WeakTypeTag]: c.Expr[ZsgSetterGeneric[H, M]] = { 34 | try { 35 | val h = c.weakTypeOf[H] 36 | val hType = h.resultType 37 | val s = symbolOf[H] 38 | val b = companionOfSymbol(s) 39 | 40 | val props = caseClassMembersByType(hType) 41 | 42 | def toTupleTree(prop: List[ModelField]): Any = { 43 | if (prop.size > 3) { 44 | @tailrec 45 | def maxSize(old: Int): Int = { 46 | val temp = old * ZsgParameters.maxPropertyNum 47 | if (temp < prop.size) maxSize(temp) else old 48 | } 49 | val size = maxSize(1) 50 | (toTupleTree(prop.take(size)), toTupleTree(prop.drop(size))) 51 | } else if (prop.size == 3) ((prop(0), prop(1)), prop(2)) 52 | else if (prop.size == 2) (prop(0), prop(1)) 53 | else prop(0) 54 | } 55 | 56 | val i1Term = TermName("i1") 57 | val i2Term = TermName("i2") 58 | 59 | def toPropertyList(n: Any): Vector[(ModelField, Tree => Tree)] = n match { 60 | case n: ModelField => Vector((n, (s: Tree) => s)) 61 | case (n1: ModelField, n2: ModelField) => 62 | val item1 = (n1, (s: Tree) => q"""$s.$i1Term""") 63 | val item2 = (n2, (s: Tree) => q"""$s.$i2Term""") 64 | Vector(item1, item2) 65 | case (t1, n: ModelField) => 66 | val list1 = toPropertyList(t1).map(s => (s._1, (t: Tree) => s._2(q"""$t.$i1Term"""))) 67 | val item2 = (n, (s: Tree) => q"""$s.$i2Term""") 68 | vectorAppend(list1, item2) 69 | case (t1, t2) => 70 | val list1 = toPropertyList(t1).map(s => (s._1, (t: Tree) => s._2(q"""$t.$i1Term"""))) 71 | val list2 = toPropertyList(t2).map(s => (s._1, (t: Tree) => s._2(q"""$t.$i2Term"""))) 72 | vectorAppendAll(list1, list2) 73 | } 74 | 75 | val casei = toPropertyList(toTupleTree(props)) 76 | 77 | val inputFunc = q"""_root_.zsg.macros.single.ZsgSetterGeneric.value(item => ${b.companionTree}.apply(..${casei.map { 78 | case (item, m) => 79 | namedParam(item.fieldTermName, m(Ident(TermName("item")))) 80 | }}))""" 81 | 82 | c.Expr[ZsgSetterGeneric[H, M]] { 83 | inputFunc 84 | } 85 | 86 | } catch { 87 | case e: Exception => 88 | e.printStackTrace 89 | throw e 90 | } 91 | } 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/deficient/AsunaTupleApply.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single.deficient 2 | 3 | import zsg.macros.single.utils.{Sha1Helper, TypeHelper} 4 | import zsg.macros.utils.MacroMethods 5 | 6 | import scala.language.experimental.macros 7 | import scala.collection.compat._ 8 | 9 | trait AsunaTupleApply[Model, TupleType] { 10 | def toTuple(gen: Model): TupleType 11 | } 12 | 13 | object AsunaTupleApply { 14 | @inline def apply[Model, TupleType](implicit asunaTupleApply: AsunaTupleApply[Model, TupleType]): AsunaTupleApply[Model, TupleType] = 15 | asunaTupleApply 16 | implicit def macroImpl[Model, TupleType]: AsunaTupleApply[Model, TupleType] = 17 | macro AsunaTupleApplyMacroApply.MacroImpl.generic[Model, TupleType] 18 | } 19 | 20 | object AsunaTupleApplyMacroApply { 21 | 22 | class MacroImpl(override val c: scala.reflect.macros.blackbox.Context) extends TypeHelper with Sha1Helper with MacroMethods { 23 | self => 24 | 25 | import c.universe._ 26 | 27 | def generic[Model: c.WeakTypeTag, TupleType: c.WeakTypeTag]: c.Expr[AsunaTupleApply[Model, TupleType]] = { 28 | try { 29 | 30 | val struct = tupleTypeNames[TupleType] 31 | 32 | val shaKey = 33 | AsunaTupleApply.getClass.getCanonicalName + c.enclosingPosition.toString + struct.modelType.typeSymbol.name.toString + struct.traitType.typeSymbol.name.toString 34 | def freshName = toSha1(shaKey + c.freshName) 35 | 36 | val shaSelf = freshName 37 | val shaSelfTerm = TermName(shaSelf) 38 | val shaSelfVal = q"""val $shaSelfTerm = $EmptyTree""" 39 | 40 | def tupleDeficientSetter = 41 | struct.tupleFields.map { pro => 42 | val argsSetter = pro.caseClassFields.map(i => 43 | namedParam(i.fieldTermName, Select(Select(Ident(shaSelfTerm), struct.modelFieldTermName), i.fieldTermName)) 44 | ) 45 | q"""override def ${pro.fieldTermName} = ${pro.fieldType.typeSymbol.companion}(..${argsSetter})""" 46 | } 47 | 48 | val shaParameterName = freshName 49 | val shaParamNameTerm = TermName(shaParameterName) 50 | val shaParameterNameVal = q"""val $shaParamNameTerm = $EmptyTree""" 51 | 52 | c.Expr[AsunaTupleApply[Model, TupleType]] { 53 | q"""{ $shaParameterNameVal => 54 | new ${struct.traitType} { 55 | $shaSelfVal => 56 | ..${tupleDeficientSetter} 57 | override val ${struct.modelFieldTermName} = $shaParamNameTerm 58 | } 59 | }""" 60 | } 61 | 62 | } catch { 63 | case e: Exception => 64 | e.printStackTrace 65 | throw e 66 | } 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/deficient/AsunaTupleGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single.deficient 2 | 3 | import zsg.macros.ZsgParameters 4 | import zsg.macros.single.utils.{Sha1Helper, TypeHelper} 5 | 6 | import scala.language.experimental.macros 7 | import scala.collection.compat._ 8 | 9 | trait AsunaTupleGeneric[TupleType] { 10 | type WT 11 | def tag: WT 12 | } 13 | 14 | object AsunaTupleGeneric { 15 | def value[T, WT1](value1: WT1): AsunaTupleGeneric.Aux[T, WT1] = 16 | new AsunaTupleGeneric[T] { 17 | override type WT = WT1 18 | override def tag: WT1 = value1 19 | } 20 | 21 | type Aux[H, II] = AsunaTupleGeneric[H] { type WT = II } 22 | 23 | implicit def macroImpl[TupleType, T]: AsunaTupleGeneric.Aux[TupleType, T] = 24 | macro AsunaTupleGenericMacroApply.MacroImpl.generic[TupleType, T] 25 | } 26 | 27 | object AsunaTupleGenericMacroApply { 28 | 29 | class MacroImpl(override val c: scala.reflect.macros.whitebox.Context) extends TypeHelper with Sha1Helper { 30 | self => 31 | 32 | import c.universe._ 33 | 34 | def generic[TupleType: c.WeakTypeTag, T: c.WeakTypeTag]: c.Expr[AsunaTupleGeneric.Aux[TupleType, T]] = { 35 | try { 36 | 37 | val tuple = weakTypeOf[TupleType] 38 | val tupleType = tuple.resultType 39 | 40 | val struct = tupleTypeNames[TupleType] 41 | val allFields = struct.tupleFields.flatMap(_.caseClassFields) 42 | val genericFields = struct.modelFields.filter(i => !allFields.exists(ii => ii.fieldName == i.fieldName)) 43 | 44 | val proTypeTag = genericFields.map(s => 45 | q"""_root_.zsg.macros.single.PropertyApply[${tupleType}].to(_.${struct.modelFieldTermName}.${s.fieldTermName})""" 46 | ) 47 | 48 | val typeTag = proTypeTag.grouped(ZsgParameters.maxPropertyNum).toList.map(i => q"""_root_.zsg.AppendTag.tag(..${i})""") 49 | def typeTagGen(tree: List[Tree]): Tree = 50 | if (tree.length == 1) { 51 | q"""..${tree}""" 52 | } else { 53 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).toList 54 | typeTagGen(groupedTree.map(s => q"""_root_.zsg.BuildContent.tuple(..${s})""")) 55 | } 56 | 57 | c.Expr[AsunaTupleGeneric.Aux[TupleType, T]] { 58 | q"""_root_.zsg.macros.single.deficient.AsunaTupleGeneric.value(${typeTagGen(typeTag)})""" 59 | } 60 | 61 | } catch { 62 | case e: Exception => 63 | e.printStackTrace 64 | throw e 65 | } 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/deficient/AsunaTupleGetterGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single.deficient 2 | 3 | import zsg.macros.ZsgParameters 4 | import zsg.macros.single.utils.{Sha1Helper, TypeHelper} 5 | 6 | import scala.language.experimental.macros 7 | import scala.collection.compat._ 8 | 9 | trait AsunaTupleGetterGeneric[H, GenericType] { 10 | def getter(model: H): GenericType 11 | } 12 | 13 | object AsunaTupleGetterGeneric { 14 | implicit def macroImpl[H, GenericType]: AsunaTupleGetterGeneric[H, GenericType] = 15 | macro AsunaTupleGetterGenericMacroApply.MacroImpl.generic[H, GenericType] 16 | } 17 | 18 | object AsunaTupleGetterGenericMacroApply { 19 | 20 | class MacroImpl(override val c: scala.reflect.macros.blackbox.Context) extends TypeHelper with Sha1Helper { 21 | self => 22 | 23 | import c.universe._ 24 | 25 | def generic[H: c.WeakTypeTag, GenericType: c.WeakTypeTag]: c.Expr[AsunaTupleGetterGeneric[H, GenericType]] = { 26 | try { 27 | val struct = tupleTypeNames[H] 28 | 29 | val allFields = struct.tupleFields.flatMap(_.caseClassFields) 30 | val genericFields = struct.modelFields.filter(i => !allFields.exists(ii => ii.fieldName == i.fieldName)) 31 | 32 | val shaKey = 33 | AsunaTupleGetterGeneric.getClass.getCanonicalName + c.enclosingPosition.toString + struct.modelType.typeSymbol.name.toString + struct.traitType.typeSymbol.name.toString 34 | def freshName = toSha1(shaKey + c.freshName) 35 | 36 | val modelParam = freshName 37 | 38 | val modelFields = genericFields.map { name => 39 | Select(Select(Ident(TermName(modelParam)), struct.modelFieldTermName), name.fieldTermName) 40 | } 41 | 42 | val paramName = q"""val ${TermName(modelParam)} = $EmptyTree""" 43 | 44 | def nameTagGen(tree: List[Tree]): Tree = 45 | if (tree.length <= ZsgParameters.maxPropertyNum) { 46 | q"""_root_.zsg.BuildContent.${TermName("tuple" + tree.length)}(..${tree})""" 47 | } else { 48 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).to(List) 49 | nameTagGen(groupedTree.map(s => q"""_root_.zsg.BuildContent.${TermName("tuple" + s.length)}(..${s})""")) 50 | } 51 | 52 | c.Expr[AsunaTupleGetterGeneric[H, GenericType]] { 53 | q"""{ $paramName => ${nameTagGen(modelFields)} }""" 54 | } 55 | 56 | } catch { 57 | case e: Exception => 58 | e.printStackTrace 59 | throw e 60 | } 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/deficient/AsunaTupleLabelledGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single.deficient 2 | 3 | import zsg.macros.ZsgParameters 4 | import zsg.macros.single.utils.{Sha1Helper, TypeHelper} 5 | 6 | import scala.language.experimental.macros 7 | import scala.collection.compat._ 8 | 9 | trait AsunaTupleLabelledGeneric[H, NameType] { 10 | def names(): NameType 11 | } 12 | 13 | object AsunaTupleLabelledGeneric { 14 | implicit def macroImpl[H, NameType]: AsunaTupleLabelledGeneric[H, NameType] = 15 | macro AsunaTupleLabelledGenericMacroApply.MacroImpl.generic[H, NameType] 16 | } 17 | 18 | object AsunaTupleLabelledGenericMacroApply { 19 | 20 | class MacroImpl(override val c: scala.reflect.macros.blackbox.Context) extends TypeHelper with Sha1Helper { 21 | self => 22 | 23 | import c.universe._ 24 | 25 | def generic[H: c.WeakTypeTag, NameType: c.WeakTypeTag]: c.Expr[AsunaTupleLabelledGeneric[H, NameType]] = { 26 | try { 27 | val struct = tupleTypeNames[H] 28 | 29 | val allFields = struct.tupleFields.flatMap(_.caseClassFields) 30 | val genericFields = struct.modelFields.filter(i => !allFields.exists(ii => ii.fieldName == i.fieldName)) 31 | 32 | val nameTag = genericFields.map { name => q"""${Literal(Constant(name.fieldName))}""" } 33 | def nameTagGen(tree: List[Tree]): Tree = 34 | if (tree.length <= ZsgParameters.maxPropertyNum) { 35 | q"""_root_.zsg.BuildContent.${TermName("tuple" + tree.length)}(..${tree})""" 36 | } else { 37 | val groupedTree = tree.grouped(ZsgParameters.maxPropertyNum).toList 38 | nameTagGen(groupedTree.map(s => q"""_root_.zsg.BuildContent.${TermName("tuple" + s.length)}(..${s})""")) 39 | } 40 | 41 | c.Expr[AsunaTupleLabelledGeneric[H, NameType]] { 42 | q"""{ () => ${nameTagGen(nameTag)} }""" 43 | } 44 | 45 | } catch { 46 | case e: Exception => 47 | e.printStackTrace 48 | throw e 49 | } 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/deficient/DeficientProperty.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single.deficient 2 | 3 | import scala.annotation.StaticAnnotation 4 | 5 | class DeficientProperty extends StaticAnnotation 6 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/deficient/ModelProperty.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single.deficient 2 | 3 | import scala.annotation.StaticAnnotation 4 | 5 | class ModelProperty extends StaticAnnotation 6 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/utils/SealedHelper.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single.utils 2 | 3 | import scala.annotation.StaticAnnotation 4 | 5 | trait SealedHelper { 6 | 7 | val c: scala.reflect.macros.blackbox.Context 8 | import c.universe._ 9 | 10 | /** If a super-type is generic, find all the subtypes, but at the same time fill in all the generic type parameters that are based on the 11 | * super-type's concrete type 12 | * @author 13 | * lihaoyi 14 | */ 15 | def fleshedOutSubtypes(tpe: Type): Set[Type] = { 16 | def classSym(tpe: Type): ClassSymbol = { 17 | val sym = tpe.typeSymbol 18 | if (!sym.isClass) 19 | c.abort(c.enclosingPosition, s"$sym is not a class or trait") 20 | 21 | val classSym = sym.asClass 22 | classSym.typeSignature // Workaround for 23 | 24 | classSym 25 | } 26 | 27 | for { 28 | subtypeSym <- classSym(tpe).knownDirectSubclasses.filter(!_.toString.contains("")) 29 | if subtypeSym.isType 30 | st = subtypeSym.asType.toType 31 | baseClsArgs = st.baseType(tpe.typeSymbol).asInstanceOf[TypeRef].args 32 | } yield { 33 | tpe match { 34 | case ExistentialType(_, TypeRef(pre, sym, args)) => 35 | st.substituteTypes(baseClsArgs.map(_.typeSymbol), args) 36 | case ExistentialType(_, _) => st 37 | case TypeRef(pre, sym, args) => 38 | st.substituteTypes(baseClsArgs.map(_.typeSymbol), args) 39 | } 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/utils/Sha1Helper.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single.utils 2 | 3 | import org.apache.commons.codec.digest.DigestUtils 4 | 5 | trait Sha1Helper { 6 | 7 | val c: scala.reflect.macros.blackbox.Context 8 | 9 | def toSha1(i: String): String = 10 | if (i.isEmpty) 11 | DigestUtils.sha1Hex(c.enclosingPosition.toString + "scala.macro") 12 | else 13 | DigestUtils.sha1Hex(i) 14 | 15 | } 16 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-2/zsg/macros/single/utils/TypeHelper.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single.utils 2 | 3 | import zsg.macros.single.deficient.{DeficientProperty, ModelProperty} 4 | 5 | import scala.collection.compat._ 6 | 7 | trait TypeHelper { 8 | 9 | val c: scala.reflect.macros.blackbox.Context 10 | import c.universe._ 11 | 12 | case class ModelField(fieldName: String, fieldSymbol: Symbol, fieldTermName: TermName) 13 | case class TupleField(fieldName: String, fieldSymbol: Symbol, fieldType: Type, fieldTermName: TermName, caseClassFields: List[ModelField]) 14 | 15 | case class TupleTypeStructure( 16 | traitType: Type, 17 | modelFieldSymbol: Symbol, 18 | modelFieldName: String, 19 | modelType: Type, 20 | modelFieldTermName: TermName, 21 | modelFields: List[ModelField], 22 | tupleFields: List[TupleField] 23 | ) 24 | 25 | def caseClassMembersByType(tpe: Type): List[ModelField] = { 26 | tpe.members 27 | .to(List) 28 | .filter(s => s.isTerm && s.asTerm.isVal && s.asTerm.isCaseAccessor) 29 | .map(s => (s, s.name)) 30 | .collect { case (symbol, TermName(n)) => 31 | val name = n.trim 32 | ModelField(name, symbol, TermName(name)) 33 | } 34 | .reverse 35 | } 36 | 37 | def tupleTypeNames[TupleType: c.WeakTypeTag]: TupleTypeStructure = { 38 | val traitType = weakTypeOf[TupleType].resultType 39 | val tupleModelProperty: Symbol = 40 | traitType.members.to(List).filter(s => s.annotations.find(s => s.tree.tpe.<:<(weakTypeOf[ModelProperty])).isDefined).head 41 | val TermName(preProName) = tupleModelProperty.name 42 | val modelFieldName = preProName.trim 43 | val modelType = tupleModelProperty.typeSignatureIn(traitType) 44 | 45 | val tupleSymbols = 46 | traitType.members.to(List).filter(s => s.annotations.find(s => s.tree.tpe.<:<(weakTypeOf[DeficientProperty])).isDefined).reverse 47 | val tupleFields = tupleSymbols.map { i => 48 | val TermName(n) = i.name 49 | val name = n.trim 50 | val fieldType = i.typeSignatureIn(traitType) 51 | TupleField( 52 | fieldName = name, 53 | fieldSymbol = i, 54 | fieldType = fieldType, 55 | caseClassFields = caseClassMembersByType(fieldType), 56 | fieldTermName = TermName(name) 57 | ) 58 | } 59 | 60 | val modelFields = caseClassMembersByType(modelType) 61 | TupleTypeStructure( 62 | traitType = traitType, 63 | modelFieldSymbol = tupleModelProperty, 64 | modelFieldName = modelFieldName, 65 | modelFieldTermName = TermName(modelFieldName), 66 | modelType = modelType, 67 | modelFields = modelFields, 68 | tupleFields = tupleFields 69 | ) 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala-3/AsunaGeneric.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | import zsg.macros.ZsgParameters 4 | 5 | import scala.language.experimental.macros 6 | 7 | case class TestModel(i1: String, i2: Int) 8 | 9 | trait AsunaGeneric[H] { 10 | type WT 11 | def tag: WT 12 | } 13 | 14 | object AsunaGeneric { 15 | 16 | val value = new AsunaGeneric[Any] { 17 | override type WT = Any 18 | override def tag: Any = 2 19 | } 20 | type Aux[H, II] = AsunaGeneric[H] { type WT = II } 21 | inline def Aux[H, II]: Aux[H, II] = value.asInstanceOf[Aux[H, II]] 22 | 23 | class GenericApply[M] { 24 | def generic[WW](implicit i: AsunaGeneric.Aux[M, WW]): AsunaGeneric.Aux[M, WW] = i 25 | @inline def value[K](i: PropertyApply[M] => K): AsunaGeneric.Aux[M, K] = Aux[M, K] 26 | } 27 | 28 | object GenericApply { 29 | val value = new GenericApply[Any] 30 | inline def apply[T]: AsunaGeneric.GenericApply[T] = value.asInstanceOf[GenericApply[T]] 31 | inline implicit def init[M]: AsunaGeneric.GenericApply[M] = GenericApply[M] 32 | } 33 | 34 | transparent inline def defaultOf[H](using inline prop: AsunaGeneric.GenericApply[H]) = ${ AsunaGenericMacroApply.generic('prop) } 35 | 36 | } 37 | 38 | object AsunaGenericMacroApply { 39 | 40 | import scala.quoted.* 41 | 42 | def generic[H](prop: Expr[AsunaGeneric.GenericApply[H]])(using qctx: Quotes, t1: Type[H]): Expr[Any] = { 43 | // import qctx.tasty._ 44 | // println(t1.unseal) 45 | prop 46 | } 47 | 48 | transparent inline def generic1[H: Type](using qctx: Quotes): Expr[Any] = { 49 | val typeRef = Type.of[H] 50 | typeRef 51 | '{ 32424 } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala/zsg/macros/ZsgParameters.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros 2 | 3 | object ZsgParameters { 4 | val maxPropertyNum = 2 5 | } 6 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala/zsg/macros/single/ColumnName.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | class ColumnName[N <: String] 4 | 5 | object ColumnName { 6 | val any = new ColumnName[Nothing] 7 | def apply[N <: String]: ColumnName[N] = any.asInstanceOf[ColumnName[N]] 8 | } 9 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala/zsg/macros/single/DebugColumnInfo.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | class DebugColumnInfo[ColumnIndex, ColumnName] 4 | 5 | object DebugColumnInfo { 6 | def apply[ColumnIndex, ColumnName]: DebugColumnInfo[ColumnIndex, ColumnName] = new DebugColumnInfo[ColumnIndex, ColumnName] 7 | } 8 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala/zsg/macros/single/InstanceApply.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | class InstanceApply { 4 | def to[ColumnIndex, ColumnName]: DebugColumnInfo[ColumnIndex, ColumnName] = DebugColumnInfo[ColumnIndex, ColumnName] 5 | } 6 | object InstanceApply { 7 | private val value: InstanceApply = new InstanceApply 8 | def apply: InstanceApply = value 9 | } 10 | -------------------------------------------------------------------------------- /modules/macros/src/main/scala/zsg/macros/single/PropertyApply.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.single 2 | 3 | import zsg.PropertyTag 4 | 5 | class PropertyApply[I] { 6 | def to[R](m: I => R): PropertyTag[R] = PropertyTag[R] 7 | } 8 | object PropertyApply { 9 | val value: PropertyApply[Any] = new PropertyApply[Any] 10 | implicit def proImplicit[I]: PropertyApply[I] = PropertyApply[I] 11 | def apply[R]: PropertyApply[R] = value.asInstanceOf[PropertyApply[R]] 12 | } 13 | -------------------------------------------------------------------------------- /modules/macros/src/test/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | # SLF4J's SimpleLogger configuration file 2 | # org.slf4j.simpleLogger.log.slick.jdbc.JdbcBackend.statement=debug 3 | # org.slf4j.simpleLogger.log.slick.jdbc.StatementInvoker.result=debug 4 | # org.slf4j.simpleLogger.log.slick.jdbc.JdbcBackend.parameter=debug -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2.13/zsg/test/macros/CaseClassLabelledGenericMacroGenPrepareTest.scala: -------------------------------------------------------------------------------- 1 | package zsg.test.macros.case_class_test 2 | 3 | import zsg.{ItemTag2, ZsgTuple2} 4 | import zsg.macros.case_class_test.{FieldModel, IntProperty, LongProperty, ModelToString, StringProperty} 5 | import zsg.macros.single.{ColumnName, PropertyApply, ZsgGetterGeneric, ZsgLabelledTypeGeneric} 6 | 7 | object CaseClassLabelledGenericMacroGenPrepareTest { 8 | 9 | case class Foo(i1: String, i2: String, i3: Int, i4: Int, i5: Long, i6: String, i7: String, i8: String, i9: Int, i10: Int) 10 | 11 | val fooValue = Foo(i1 = "i1", i2 = "i2", i3 = 3, i4 = 4, i5 = 5L, i6 = "i6", i7 = "i7", i8 = "i8", i9 = 9, i10 = 10) 12 | 13 | val ap = PropertyApply[Foo] 14 | 15 | val fooPropertyTag = ItemTag2( 16 | ItemTag2( 17 | ItemTag2(ItemTag2(ap.to(_.i1), ap.to(_.i2)), ItemTag2(ap.to(_.i3), ap.to(_.i4))), 18 | ItemTag2(ItemTag2(ap.to(_.i5), ap.to(_.i6)), ItemTag2(ap.to(_.i7), ap.to(_.i8))) 19 | ), 20 | ItemTag2(ap.to(_.i9), ap.to(_.i10)) 21 | ) 22 | 23 | val fooGetter = (foo: Foo) => 24 | new ZsgTuple2( 25 | new ZsgTuple2( 26 | new ZsgTuple2(new ZsgTuple2(foo.i1, foo.i2), new ZsgTuple2(foo.i3, foo.i4)), 27 | new ZsgTuple2(new ZsgTuple2(foo.i5, foo.i6), new ZsgTuple2(foo.i7, foo.i8)) 28 | ), 29 | new ZsgTuple2(foo.i9, foo.i10) 30 | ) 31 | 32 | lazy val dsfsdfewrene: Foo = throw new Exception 33 | 34 | val fooLabelled = ZsgLabelledTypeGeneric[Foo].model( 35 | ItemTag2( 36 | ItemTag2( 37 | ItemTag2(ItemTag2(ColumnName["i1"], ColumnName["i2"]), ItemTag2(ColumnName["i3"], ColumnName["i4"])), 38 | ItemTag2(ItemTag2(ColumnName["i5"], ColumnName["i6"]), ItemTag2(ColumnName["i7"], ColumnName["i8"])) 39 | ), 40 | ItemTag2(ColumnName["i9"], ColumnName["i10"]) 41 | ) 42 | ) 43 | 44 | val fooEncoder: ModelToString[Foo] = 45 | ModelToString.init1(ModelToString.forType[Foo].value(fooPropertyTag), fooLabelled).init2.init3(ZsgGetterGeneric.value(fooGetter)) 46 | val fooEncoder2: ModelToString[Foo] = ModelToString.encoder 47 | 48 | def prepareResult(foo: Foo) = 49 | List( 50 | FieldModel(value = StringProperty(foo.i1), fieldIndex = 1, fieldName = "i1", typeName = "String"), 51 | FieldModel(value = StringProperty(foo.i2), fieldIndex = 2, fieldName = "i2", typeName = "String"), 52 | FieldModel(value = IntProperty(foo.i3), fieldIndex = 3, fieldName = "i3", typeName = "Int"), 53 | FieldModel(value = IntProperty(foo.i4), fieldIndex = 4, fieldName = "i4", typeName = "Int"), 54 | FieldModel(value = LongProperty(foo.i5), fieldIndex = 5, fieldName = "i5", typeName = "Long"), 55 | FieldModel(value = StringProperty(foo.i6), fieldIndex = 6, fieldName = "i6", typeName = "String"), 56 | FieldModel(value = StringProperty(foo.i7), fieldIndex = 7, fieldName = "i7", typeName = "String"), 57 | FieldModel(value = StringProperty(foo.i8), fieldIndex = 8, fieldName = "i8", typeName = "String"), 58 | FieldModel(value = IntProperty(foo.i9), fieldIndex = 9, fieldName = "i9", typeName = "Int"), 59 | FieldModel(value = IntProperty(foo.i10), fieldIndex = 10, fieldName = "i10", typeName = "Int") 60 | ) 61 | 62 | } 63 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2.13/zsg/test/macros/CaseClassLabelledGenericMacroGenTest.scala: -------------------------------------------------------------------------------- 1 | package zsg.test.macros.case_class_test 2 | 3 | import zio.Console._ 4 | import zio.test._ 5 | import zio.test.Assertion._ 6 | import zio.test.environment._ 7 | 8 | object CaseClassLabelledGenericMacroGenTest extends DefaultRunnableSpec { 9 | 10 | override def spec = suite("A case class")( 11 | test("should labelled generic to a encoder") { 12 | import CaseClassLabelledGenericMacroGenPrepareTest._ 13 | val str1 = fooEncoder.mToString(fooValue) 14 | val str2 = fooEncoder2.mToString(fooValue) 15 | 16 | val assert1 = assert(str1)(equalTo(prepareResult(fooValue))) 17 | val assert2 = assert(str2)(equalTo(prepareResult(fooValue))) 18 | val assert3 = assert(str1)(equalTo(str2)) 19 | assert1 && assert2 && assert3 20 | } 21 | ) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2/zsg/macros/case_class_test/codegen/CaseClassTest1.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.case_class_test 2 | import zsg.macros.single.PropertyApply 3 | import scala.collection.compat._ 4 | import zio._ 5 | import zio.Console._ 6 | import zio.test._ 7 | import zio.test.Assertion._ 8 | import zio.test.environment._ 9 | object CaseClassTest1 extends DefaultRunnableSpec { 10 | case class Foo1( i1: Long ) { 11 | self => 12 | def fieldNames: List[String] = List( "i1" ) 13 | def defaultValues: List[DefaultValue] = List( DefaultValue(value = Option.empty, fieldIndex = 1) ) 14 | def fieldInfo: List[FieldModel] = 15 | List( FieldModel(value = LongProperty(self.i1) , fieldIndex = 1, fieldName = "i1", typeName = "Long" ) ) 16 | def reverseFieldInfo: List[FieldModel] = 17 | List( FieldModel(value = LongProperty(self.i1) , fieldIndex = 1, fieldName = "i1", typeName = "Long" ) ) 18 | } 19 | val fooValue1 = Foo1( i1 = 225523422542L ) 20 | val fooEncoder1: ModelToString[Foo1] = ModelToString.encoder 21 | val reverseFooEncoder1: ModelToString[Foo1] = ModelToString.reverseEncoder 22 | val fooDecoder1: ModelFromString[Foo1] = ModelFromString.decoder 23 | val reverseFooDecoder1: ModelFromString[Foo1] = ModelFromString.reverseDecoder 24 | override def spec = suite("A case class by 1 length")( 25 | zio.test.test("should generic to a encoder") { 26 | val str1 = fooEncoder1.mToString(fooValue1) 27 | assert(str1)(equalTo(fooValue1.fieldInfo)) 28 | }, 29 | zio.test.test("should generic to a reverse encoder") { 30 | val str2 = reverseFooEncoder1.mToString(fooValue1) 31 | assert(str2)(equalTo(fooValue1.reverseFieldInfo)) 32 | }, 33 | zio.test.test("should generic to it's default value") { 34 | val str2 = fooEncoder1.defaultValues 35 | assert(str2)(equalTo(fooValue1.defaultValues)) 36 | }, 37 | zio.test.test("should generic to it's name list") { 38 | val name1 = fooEncoder1.labelledNames 39 | assert(name1)(equalTo(fooValue1.fieldNames)) 40 | }, 41 | zio.test.test("should generic to it's reverse name list") { 42 | val name1 = reverseFooEncoder1.labelledNames 43 | assert(name1)(equalTo(fooValue1.fieldNames.reverse)) 44 | }, 45 | zio.test.test("should generic to a decoder") { 46 | val (_, model1) = fooDecoder1.getData(fooValue1.fieldInfo) 47 | assert(model1)(equalTo(fooValue1)) 48 | }, 49 | zio.test.test("should generic to a reverse decoder") { 50 | val (_, model2) = reverseFooDecoder1.getData(fooValue1.reverseFieldInfo) 51 | assert(model2)(equalTo(fooValue1)) 52 | } 53 | ) 54 | } 55 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2/zsg/macros/case_class_test/codegen/CaseClassTest2.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.case_class_test 2 | import zsg.macros.single.PropertyApply 3 | import scala.collection.compat._ 4 | import zio._ 5 | import zio.Console._ 6 | import zio.test._ 7 | import zio.test.Assertion._ 8 | import zio.test.environment._ 9 | object CaseClassTest2 extends DefaultRunnableSpec { 10 | case class Foo2( i1: Long , i2: Int ) { 11 | self => 12 | def fieldNames: List[String] = List( "i1" , "i2" ) 13 | def defaultValues: List[DefaultValue] = List( DefaultValue(value = Option.empty, fieldIndex = 1) , DefaultValue(value = Option.empty, fieldIndex = 2) ) 14 | def fieldInfo: List[FieldModel] = 15 | List( FieldModel(value = LongProperty(self.i1) , fieldIndex = 1, fieldName = "i1", typeName = "Long" ) , FieldModel(value = IntProperty(self.i2) , fieldIndex = 2, fieldName = "i2", typeName = "Int" ) ) 16 | def reverseFieldInfo: List[FieldModel] = 17 | List( FieldModel(value = IntProperty(self.i2) , fieldIndex = 2, fieldName = "i2", typeName = "Int" ) , FieldModel(value = LongProperty(self.i1) , fieldIndex = 1, fieldName = "i1", typeName = "Long" ) ) 18 | } 19 | val fooValue2 = Foo2( i1 = 225523422542L , i2 = 88 ) 20 | val fooEncoder2: ModelToString[Foo2] = ModelToString.encoder 21 | val reverseFooEncoder2: ModelToString[Foo2] = ModelToString.reverseEncoder 22 | val fooDecoder2: ModelFromString[Foo2] = ModelFromString.decoder 23 | val reverseFooDecoder2: ModelFromString[Foo2] = ModelFromString.reverseDecoder 24 | override def spec = suite("A case class by 2 length")( 25 | zio.test.test("should generic to a encoder") { 26 | val str1 = fooEncoder2.mToString(fooValue2) 27 | assert(str1)(equalTo(fooValue2.fieldInfo)) 28 | }, 29 | zio.test.test("should generic to a reverse encoder") { 30 | val str2 = reverseFooEncoder2.mToString(fooValue2) 31 | assert(str2)(equalTo(fooValue2.reverseFieldInfo)) 32 | }, 33 | zio.test.test("should generic to it's default value") { 34 | val str2 = fooEncoder2.defaultValues 35 | assert(str2)(equalTo(fooValue2.defaultValues)) 36 | }, 37 | zio.test.test("should generic to it's name list") { 38 | val name1 = fooEncoder2.labelledNames 39 | assert(name1)(equalTo(fooValue2.fieldNames)) 40 | }, 41 | zio.test.test("should generic to it's reverse name list") { 42 | val name1 = reverseFooEncoder2.labelledNames 43 | assert(name1)(equalTo(fooValue2.fieldNames.reverse)) 44 | }, 45 | zio.test.test("should generic to a decoder") { 46 | val (_, model1) = fooDecoder2.getData(fooValue2.fieldInfo) 47 | assert(model1)(equalTo(fooValue2)) 48 | }, 49 | zio.test.test("should generic to a reverse decoder") { 50 | val (_, model2) = reverseFooDecoder2.getData(fooValue2.reverseFieldInfo) 51 | assert(model2)(equalTo(fooValue2)) 52 | } 53 | ) 54 | } 55 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2/zsg/macros/case_class_test/codegen/CaseClassTest3.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.case_class_test 2 | import zsg.macros.single.PropertyApply 3 | import scala.collection.compat._ 4 | import zio._ 5 | import zio.Console._ 6 | import zio.test._ 7 | import zio.test.Assertion._ 8 | import zio.test.environment._ 9 | object CaseClassTest3 extends DefaultRunnableSpec { 10 | case class Foo3( i1: Long , i2: Int , i3: Int ) { 11 | self => 12 | def fieldNames: List[String] = List( "i1" , "i2" , "i3" ) 13 | def defaultValues: List[DefaultValue] = List( DefaultValue(value = Option.empty, fieldIndex = 1) , DefaultValue(value = Option.empty, fieldIndex = 2) , DefaultValue(value = Option.empty, fieldIndex = 3) ) 14 | def fieldInfo: List[FieldModel] = 15 | List( FieldModel(value = LongProperty(self.i1) , fieldIndex = 1, fieldName = "i1", typeName = "Long" ) , FieldModel(value = IntProperty(self.i2) , fieldIndex = 2, fieldName = "i2", typeName = "Int" ) , FieldModel(value = IntProperty(self.i3) , fieldIndex = 3, fieldName = "i3", typeName = "Int" ) ) 16 | def reverseFieldInfo: List[FieldModel] = 17 | List( FieldModel(value = IntProperty(self.i3) , fieldIndex = 3, fieldName = "i3", typeName = "Int" ) , FieldModel(value = IntProperty(self.i2) , fieldIndex = 2, fieldName = "i2", typeName = "Int" ) , FieldModel(value = LongProperty(self.i1) , fieldIndex = 1, fieldName = "i1", typeName = "Long" ) ) 18 | } 19 | val fooValue3 = Foo3( i1 = 225523422542L , i2 = 88 , i3 = 82 ) 20 | val fooEncoder3: ModelToString[Foo3] = ModelToString.encoder 21 | val reverseFooEncoder3: ModelToString[Foo3] = ModelToString.reverseEncoder 22 | val fooDecoder3: ModelFromString[Foo3] = ModelFromString.decoder 23 | val reverseFooDecoder3: ModelFromString[Foo3] = ModelFromString.reverseDecoder 24 | override def spec = suite("A case class by 3 length")( 25 | zio.test.test("should generic to a encoder") { 26 | val str1 = fooEncoder3.mToString(fooValue3) 27 | assert(str1)(equalTo(fooValue3.fieldInfo)) 28 | }, 29 | zio.test.test("should generic to a reverse encoder") { 30 | val str2 = reverseFooEncoder3.mToString(fooValue3) 31 | assert(str2)(equalTo(fooValue3.reverseFieldInfo)) 32 | }, 33 | zio.test.test("should generic to it's default value") { 34 | val str2 = fooEncoder3.defaultValues 35 | assert(str2)(equalTo(fooValue3.defaultValues)) 36 | }, 37 | zio.test.test("should generic to it's name list") { 38 | val name1 = fooEncoder3.labelledNames 39 | assert(name1)(equalTo(fooValue3.fieldNames)) 40 | }, 41 | zio.test.test("should generic to it's reverse name list") { 42 | val name1 = reverseFooEncoder3.labelledNames 43 | assert(name1)(equalTo(fooValue3.fieldNames.reverse)) 44 | }, 45 | zio.test.test("should generic to a decoder") { 46 | val (_, model1) = fooDecoder3.getData(fooValue3.fieldInfo) 47 | assert(model1)(equalTo(fooValue3)) 48 | }, 49 | zio.test.test("should generic to a reverse decoder") { 50 | val (_, model2) = reverseFooDecoder3.getData(fooValue3.reverseFieldInfo) 51 | assert(model2)(equalTo(fooValue3)) 52 | } 53 | ) 54 | } 55 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2/zsg/macros/case_class_test/codegen/CaseClassTest4.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.case_class_test 2 | import zsg.macros.single.PropertyApply 3 | import scala.collection.compat._ 4 | import zio._ 5 | import zio.Console._ 6 | import zio.test._ 7 | import zio.test.Assertion._ 8 | import zio.test.environment._ 9 | object CaseClassTest4 extends DefaultRunnableSpec { 10 | case class Foo4( i1: Long , i2: Int , i3: Int , i4: Long ) { 11 | self => 12 | def fieldNames: List[String] = List( "i1" , "i2" , "i3" , "i4" ) 13 | def defaultValues: List[DefaultValue] = List( DefaultValue(value = Option.empty, fieldIndex = 1) , DefaultValue(value = Option.empty, fieldIndex = 2) , DefaultValue(value = Option.empty, fieldIndex = 3) , DefaultValue(value = Option.empty, fieldIndex = 4) ) 14 | def fieldInfo: List[FieldModel] = 15 | List( FieldModel(value = LongProperty(self.i1) , fieldIndex = 1, fieldName = "i1", typeName = "Long" ) , FieldModel(value = IntProperty(self.i2) , fieldIndex = 2, fieldName = "i2", typeName = "Int" ) , FieldModel(value = IntProperty(self.i3) , fieldIndex = 3, fieldName = "i3", typeName = "Int" ) , FieldModel(value = LongProperty(self.i4) , fieldIndex = 4, fieldName = "i4", typeName = "Long" ) ) 16 | def reverseFieldInfo: List[FieldModel] = 17 | List( FieldModel(value = LongProperty(self.i4) , fieldIndex = 4, fieldName = "i4", typeName = "Long" ) , FieldModel(value = IntProperty(self.i3) , fieldIndex = 3, fieldName = "i3", typeName = "Int" ) , FieldModel(value = IntProperty(self.i2) , fieldIndex = 2, fieldName = "i2", typeName = "Int" ) , FieldModel(value = LongProperty(self.i1) , fieldIndex = 1, fieldName = "i1", typeName = "Long" ) ) 18 | } 19 | val fooValue4 = Foo4( i1 = 225523422542L , i2 = 88 , i3 = 82 , i4 = 24564564L ) 20 | val fooEncoder4: ModelToString[Foo4] = ModelToString.encoder 21 | val reverseFooEncoder4: ModelToString[Foo4] = ModelToString.reverseEncoder 22 | val fooDecoder4: ModelFromString[Foo4] = ModelFromString.decoder 23 | val reverseFooDecoder4: ModelFromString[Foo4] = ModelFromString.reverseDecoder 24 | override def spec = suite("A case class by 4 length")( 25 | zio.test.test("should generic to a encoder") { 26 | val str1 = fooEncoder4.mToString(fooValue4) 27 | assert(str1)(equalTo(fooValue4.fieldInfo)) 28 | }, 29 | zio.test.test("should generic to a reverse encoder") { 30 | val str2 = reverseFooEncoder4.mToString(fooValue4) 31 | assert(str2)(equalTo(fooValue4.reverseFieldInfo)) 32 | }, 33 | zio.test.test("should generic to it's default value") { 34 | val str2 = fooEncoder4.defaultValues 35 | assert(str2)(equalTo(fooValue4.defaultValues)) 36 | }, 37 | zio.test.test("should generic to it's name list") { 38 | val name1 = fooEncoder4.labelledNames 39 | assert(name1)(equalTo(fooValue4.fieldNames)) 40 | }, 41 | zio.test.test("should generic to it's reverse name list") { 42 | val name1 = reverseFooEncoder4.labelledNames 43 | assert(name1)(equalTo(fooValue4.fieldNames.reverse)) 44 | }, 45 | zio.test.test("should generic to a decoder") { 46 | val (_, model1) = fooDecoder4.getData(fooValue4.fieldInfo) 47 | assert(model1)(equalTo(fooValue4)) 48 | }, 49 | zio.test.test("should generic to a reverse decoder") { 50 | val (_, model2) = reverseFooDecoder4.getData(fooValue4.reverseFieldInfo) 51 | assert(model2)(equalTo(fooValue4)) 52 | } 53 | ) 54 | } 55 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2/zsg/test/macros/case_class_test/ModelFromString.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.case_class_test 2 | 3 | import zsg.macros.single.{ZsgGeneric, ZsgSetterGeneric} 4 | import zsg.{ItemTag2, PropertyTag, ZsgTuple2} 5 | 6 | trait ModelFromString[M] { 7 | def getData(str: List[FieldModel]): (List[FieldModel], M) 8 | } 9 | 10 | object ModelFromString { 11 | 12 | trait MFSI[Input] { 13 | type M 14 | def getData(str: List[FieldModel]): (List[FieldModel], M) 15 | } 16 | object MFSI { 17 | type Aux[Input, M1] = MFSI[Input] { type M = M1 } 18 | implicit def impl[T1, T2, I1, I2](implicit 19 | i1: MFSI.Aux[T1, I1], 20 | i2: MFSI.Aux[T2, I2] 21 | ): MFSI.Aux[ItemTag2[T1, T2], ZsgTuple2[I1, I2]] = 22 | new MFSI[ItemTag2[T1, T2]] { 23 | override type M = ZsgTuple2[I1, I2] 24 | override def getData(str: List[FieldModel]): (List[FieldModel], ZsgTuple2[I1, I2]) = { 25 | val (str1, d1) = i1.getData(str) 26 | val (str2, d2) = i2.getData(str1) 27 | (str2, new ZsgTuple2(d1, d2)) 28 | } 29 | } 30 | 31 | implicit def implicit1[I1](implicit impl: ModelFromStringImpl[I1]): MFSI.Aux[PropertyTag[I1], I1] = new MFSI[PropertyTag[I1]] { 32 | override type M = I1 33 | override def getData(str: List[FieldModel]): (List[FieldModel], I1) = impl.getData(str) 34 | } 35 | } 36 | 37 | trait ReverseMFSI[Input] { 38 | type M 39 | def getData(str: List[FieldModel]): (List[FieldModel], M) 40 | } 41 | object ReverseMFSI { 42 | type Aux[Input, M1] = ReverseMFSI[Input] { type M = M1 } 43 | implicit def impl[T1, T2, I1, I2](implicit 44 | i1: ReverseMFSI.Aux[T1, I1], 45 | i2: ReverseMFSI.Aux[T2, I2] 46 | ): ReverseMFSI.Aux[ItemTag2[T1, T2], ZsgTuple2[I1, I2]] = 47 | new ReverseMFSI[ItemTag2[T1, T2]] { 48 | override type M = ZsgTuple2[I1, I2] 49 | override def getData(str: List[FieldModel]): (List[FieldModel], ZsgTuple2[I1, I2]) = { 50 | val (str1, d1) = i2.getData(str) 51 | val (str2, d2) = i1.getData(str1) 52 | (str2, new ZsgTuple2(d2, d1)) 53 | } 54 | } 55 | 56 | implicit def implicit1[I1](implicit impl: ModelFromStringImpl[I1]): ReverseMFSI.Aux[PropertyTag[I1], I1] = 57 | new ReverseMFSI[PropertyTag[I1]] { 58 | override type M = I1 59 | override def getData(str: List[FieldModel]): (List[FieldModel], I1) = impl.getData(str) 60 | } 61 | } 62 | 63 | def decoder[I1, I2, I3](implicit 64 | ii: ZsgGeneric.Aux[I1, I2], 65 | pp: MFSI.Aux[I2, I3], 66 | zsgSetterGeneric: ZsgSetterGeneric[I1, I3] 67 | ): ModelFromString[I1] = new ModelFromString[I1] { 68 | override def getData(str: List[FieldModel]): (List[FieldModel], I1) = { 69 | val (str1, m) = pp.getData(str) 70 | (str1, zsgSetterGeneric.setter(m)) 71 | } 72 | } 73 | 74 | def reverseDecoder[I1, I2, I3](implicit 75 | ii: ZsgGeneric.Aux[I1, I2], 76 | pp: ReverseMFSI.Aux[I2, I3], 77 | zsgSetterGeneric: ZsgSetterGeneric[I1, I3] 78 | ): ModelFromString[I1] = new ModelFromString[I1] { 79 | override def getData(str: List[FieldModel]): (List[FieldModel], I1) = { 80 | val (str1, m) = pp.getData(str) 81 | (str1, zsgSetterGeneric.setter(m)) 82 | } 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2/zsg/test/macros/case_class_test/ModelFromStringImpl.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.case_class_test 2 | 3 | trait ModelFromStringImpl[M] { 4 | def getData(str: List[FieldModel]): (List[FieldModel], M) 5 | } 6 | 7 | object ModelFromStringImpl { 8 | implicit val outImplicit1: ModelFromStringImpl[String] = new ModelFromStringImpl[String] { 9 | override def getData(str: List[FieldModel]): (List[FieldModel], String) = { 10 | str match { 11 | case FieldModel(StringProperty(value), _, _, _) :: tail => (tail, value) 12 | } 13 | } 14 | } 15 | 16 | implicit val outImplicit2: ModelFromStringImpl[Int] = new ModelFromStringImpl[Int] { 17 | override def getData(str: List[FieldModel]): (List[FieldModel], Int) = { 18 | str match { 19 | case FieldModel(IntProperty(value), _, _, _) :: tail => (tail, value) 20 | } 21 | } 22 | } 23 | 24 | implicit val outImplicit3: ModelFromStringImpl[Long] = new ModelFromStringImpl[Long] { 25 | override def getData(str: List[FieldModel]): (List[FieldModel], Long) = { 26 | str match { 27 | case FieldModel(LongProperty(value), _, _, _) :: tail => (tail, value) 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2/zsg/test/macros/case_class_test/PropertyItem.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.case_class_test 2 | 3 | sealed trait PropertyItem 4 | 5 | case class IntProperty(i: Int) extends PropertyItem { 6 | override def toString = s"Int(${i})" 7 | } 8 | 9 | case class StringProperty(i: String) extends PropertyItem { 10 | override def toString = s"String(${i})" 11 | } 12 | 13 | case class LongProperty(i: Long) extends PropertyItem { 14 | override def toString = s"Long(${i})" 15 | } 16 | 17 | case class DefaultValue(value: Option[PropertyItem], fieldIndex: Int) 18 | 19 | case class FieldModel(value: PropertyItem, fieldIndex: Int, fieldName: String, typeName: String) 20 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2/zsg/test/macros/rep_encoder_test/MutiplyClassGenericPrepareTest.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.rep_encoder_test 2 | 3 | import zsg.{Application, Context, Plus, PropertyTag, TypeAlias, TypeFunction, TypeHList} 4 | import zsg.macros.multiply.{RootTable, ZsgMultiplyGeneric, ZsgMultiplyRepGeneric} 5 | 6 | import scala.annotation.meta.getter 7 | 8 | object MutiplyClassGenericPrepareTest { 9 | 10 | class GetterType extends TypeFunction { 11 | override type H[T <: TypeHList] = Getter[T#Head] 12 | } 13 | object GetterType { 14 | implicit def implicit1[I]: Application[GetterType, PropertyTag[I], TypeAlias.TypeHList1[I]] = 15 | new Application[GetterType, PropertyTag[I], TypeAlias.TypeHList1[I]] { 16 | override def application(context: Context[GetterType]): Getter[I] = new Getter[I] 17 | } 18 | } 19 | 20 | object GetterContext extends Context[GetterType] { 21 | override def append[X <: TypeHList, Y <: TypeHList, Z <: TypeHList](x: Getter[X#Head], y: Getter[Y#Head])( 22 | plus: Plus[X, Y, Z] 23 | ): Getter[Z#Head] = new Getter[Z#Head] 24 | } 25 | 26 | class CirceGenericApply2[Model] { 27 | def encoder[Table, II, M <: TypeHList](table: Table)(implicit 28 | i: ZsgMultiplyGeneric.Aux[Table, Model, II], 29 | p: Application[GetterType, II, M], 30 | m: ZsgMultiplyRepGeneric[Table, Model, M#Head] 31 | ): M#Head = m.rep(table) 32 | } 33 | 34 | class Getter[Model] 35 | 36 | def link[Model]: CirceGenericApply2[Model] = new CirceGenericApply2[Model] 37 | 38 | case class InstanceModel(ab: Long, cd: String, ef: Long) 39 | 40 | object mmm { 41 | val ef: Long = 123456789 42 | } 43 | object Abc { 44 | val ab: Int = 1 45 | val cd: List[String] = List("1234") 46 | @RootTable 47 | val mmmab = mmm 48 | } 49 | trait iii { 50 | val obj: Abc.type 51 | val ab: String = "p" 52 | } 53 | object model extends iii { 54 | @RootTable 55 | override val obj = Abc 56 | override val ab: String = "override p" 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2/zsg/test/macros/rep_encoder_test/MutiplyClassGenericTest.scala: -------------------------------------------------------------------------------- 1 | package zsg.macros.rep_encoder_test 2 | 3 | import zio.Console._ 4 | import zio.test._ 5 | import zio.test.Assertion._ 6 | import zio.test.environment._ 7 | 8 | object MutiplyClassGenericTest extends DefaultRunnableSpec { 9 | 10 | override def spec = suite("Rep Mapper")( 11 | test("should map mutiply class") { 12 | import MutiplyClassGenericPrepareTest._ 13 | 14 | val linkModel = link[InstanceModel].encoder(model) 15 | 16 | linkModel.i1.i1: String 17 | linkModel.i1.i2: List[String] 18 | linkModel.i2: Long 19 | 20 | val assert1 = assert(linkModel.i2)(equalTo(mmm.ef)) 21 | val assert2 = assert(linkModel.i2)(equalTo(model.obj.mmmab.ef)) 22 | val assert3 = assert(linkModel.i1.i1)(equalTo(model.ab)) 23 | val assert4 = assert(linkModel.i1.i2)(equalTo(model.obj.cd)) 24 | val assert5 = !assert(linkModel.i1.i1: Any)(equalTo(model.obj.ab: Any)) 25 | assert1 && assert2 && assert3 && assert4 && assert5 26 | } 27 | ) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2/zsg/test/macros/sealed_trait_test/SealedTraitLabelledGenericPrepareTest.scala: -------------------------------------------------------------------------------- 1 | package zsg.test.macros.sealed_trait_test 2 | 3 | import zsg.{Application, Context, Plus, TypeAlias, TypeFunction, TypeHList} 4 | import zsg.macros.single.{SealedTag, ZsgSealedGeneric, ZsgSealedLabelledGeneric} 5 | 6 | object SealedTraitLabelledGenericPrepareTest { 7 | 8 | sealed trait Abc[T] 9 | 10 | class AA(ii: String, iiii: String) extends Abc[String] 11 | class BB(ii: String, iiii: String) extends Abc[String] 12 | case class CC(i1: Number, i2: String) extends Abc[Number] 13 | case object dd extends Abc[Number] 14 | 15 | class Ignore(ii: String, iiii: String) extends BB(ii, iiii) 16 | 17 | trait SealedNameGetter[T] { 18 | def stt(t: T): List[String] => List[String] 19 | } 20 | 21 | trait SealedTraitNames[H] { 22 | def str: List[String] 23 | } 24 | 25 | class SeaGetter extends TypeFunction { 26 | override type H[T <: TypeHList] = SealedNameGetter[T#Head] 27 | } 28 | 29 | def sealedNames[H, T, TT <: TypeHList](implicit 30 | sg: ZsgSealedGeneric.Aux[H, T], 31 | app: Application[SeaGetter, T, TT], 32 | labelled: ZsgSealedLabelledGeneric[H, TT#Head] 33 | ): SealedTraitNames[H] = new SealedTraitNames[H] { 34 | override def str: List[String] = app.application(SealedNameGetterContext.value).stt(labelled.names)(List.empty) 35 | } 36 | 37 | class SealedNameGetterContext extends Context[SeaGetter] { 38 | override def append[X <: TypeHList, Y <: TypeHList, Z <: TypeHList](x: SealedNameGetter[X#Head], y: SealedNameGetter[Y#Head])( 39 | plus: Plus[X, Y, Z] 40 | ): SealedNameGetter[Z#Head] = new SealedNameGetter[Z#Head] { 41 | override def stt(t: Z#Head): List[String] => List[String] = { 42 | val xh = x.stt(plus.takeHead(t)) 43 | val yh = y.stt(plus.takeTail(t)) 44 | ii => xh(yh(ii)) 45 | } 46 | } 47 | } 48 | 49 | object SealedNameGetterContext { 50 | val value: SealedNameGetterContext = new SealedNameGetterContext 51 | } 52 | 53 | implicit def stringImplicit1[T]: Application[SeaGetter, SealedTag[T], TypeAlias.TypeHList1[String]] = 54 | new Application[SeaGetter, SealedTag[T], TypeAlias.TypeHList1[String]] { 55 | override def application(context: Context[SeaGetter]): SealedNameGetter[String] = new SealedNameGetter[String] { 56 | override def stt(t: String): List[String] => List[String] = list => t :: list 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-2/zsg/test/macros/sealed_trait_test/SealedTraitLabelledGenericTest.scala: -------------------------------------------------------------------------------- 1 | package zsg.test.macros.sealed_trait_test 2 | 3 | import zio.Console._ 4 | import zio.test._ 5 | import zio.test.Assertion._ 6 | import zio.test.environment._ 7 | 8 | object SealedTraitLabelledGenericTest extends DefaultRunnableSpec { 9 | 10 | override def spec = suite("A sealed trait")( 11 | test("should labelled generic to it's names") { 12 | import SealedTraitLabelledGenericPrepareTest._ 13 | 14 | val names1: SealedTraitNames[Abc[String]] = sealedNames 15 | val assert1 = assert(names1.str)(equalTo(List("AA", "BB", "CC", "dd"))) 16 | val assert2 = assert(new Ignore(ii = "12135dsfsf", iiii = "2").isInstanceOf[Abc[String]])(equalTo(true)) 17 | val assert3 = assert(names1.str.contains("Ignore"))(equalTo(false)) 18 | val assert4 = assert(names1.str.contains("BB"))(equalTo(true)) 19 | assert1 && assert2 && assert3 && assert4 20 | } 21 | ) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /modules/macros/src/test/scala-3/MacroTest.scala: -------------------------------------------------------------------------------- 1 | package n 2 | 3 | import zio._ 4 | import zio.Console._ 5 | import zio.test._ 6 | import zio.test.Assertion._ 7 | import zio.test.environment._ 8 | 9 | object MacroTest extends DefaultRunnableSpec { 10 | 11 | override def spec = suite("Confim macro tree")( 12 | test("macro tree should equal the word provide") { 13 | for { 14 | _ <- print(zsg.macros.single.AsunaGeneric.defaultOf.getClass.getName) 15 | word1 <- TestConsole.output 16 | word2 <- ZIO.attempt("zsg.macros.single.AsunaGeneric$GenericApply") 17 | } yield assert(word1)(equalTo(Vector(word2))) 18 | } 19 | ) 20 | 21 | /*def main(u: Array[String]): Unit = { 22 | // TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),module scala),Any)] 23 | println(zsg.macros.single.AsunaGeneric.defaultOf) 24 | }*/ 25 | 26 | } 27 | -------------------------------------------------------------------------------- /modules/macros/src/test1/scala/bb.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | import zsg.macros.single.{ColumnName, GenericColumnName, ZsgLabelledTypeGeneric} 4 | 5 | case class TestModel(i1: String, iassfasf2: Int, i3: String) 6 | 7 | object TestModel extends App { 8 | class bb[T] { 9 | def model[M](implicit modelgeneric: ZsgLabelledTypeGeneric.Aux[T, M]): M = modelgeneric.tag 10 | } 11 | def cc[T](n: ColumnName[T])(implicit nn: GenericColumnName[T]): String = nn.value 12 | def model[T]: bb[T] = new bb[T] 13 | 14 | println(cc(model[TestModel].model.i2)) 15 | } 16 | -------------------------------------------------------------------------------- /modules/macros/version.sbt: -------------------------------------------------------------------------------- 1 | CommonSettings.projectVersionSetting 2 | name := "zsg-macros" 3 | -------------------------------------------------------------------------------- /modules/rep/build.sbt: -------------------------------------------------------------------------------- 1 | ZsgSettings.settings.dottyVersion 2 | CommonSettings.settings 3 | 4 | libraryDependencies ++= Dependencies.zioTest 5 | -------------------------------------------------------------------------------- /modules/rep/src/main/scala/zsg/RepMerge.scala: -------------------------------------------------------------------------------- 1 | package zsg 2 | 3 | abstract class OptionRepTaker[T, R] { 4 | def take(t: T): Option[R] 5 | } 6 | 7 | object OptionRepTaker extends OptionRepTakerImplicitImpl { 8 | implicit def zsgTuple2OptionRepTakerTuple2[T1, T2, R](implicit 9 | i1: OptionRepTaker[T1, R], 10 | i2: OptionRepTaker[T2, R] 11 | ): OptionRepTaker[ZsgTuple2[T1, T2], R] = 12 | new OptionRepTaker[ZsgTuple2[T1, T2], R] { 13 | override def take(v1: ZsgTuple2[T1, T2]): Option[R] = (i1.take(v1.i1), i2.take(v1.i2)) match { 14 | case (Some(x1), Some(_)) => Option(x1) 15 | case (Some(x1), None) => Option(x1) 16 | case (None, Some(x2)) => Option(x2) 17 | case (None, None) => Option.empty 18 | } 19 | } 20 | implicit def zsgTuple2OptionRepTakerIdentity[R]: OptionRepTaker[R, R] = new OptionRepTaker[R, R] { 21 | override def take(v1: R): Option[R] = Option(v1) 22 | } 23 | } 24 | 25 | trait OptionRepTakerImplicitImpl { 26 | implicit def zsgTuple2OptionRepTakerNone[R, T]: OptionRepTaker[T, R] = new OptionRepTaker[T, R] { 27 | override def take(v1: T): Option[R] = Option.empty 28 | } 29 | } 30 | 31 | trait RepMerge { 32 | implicit class mergeExtensionMethod[T](t: T) { 33 | def merge[N](n: N): ZsgTuple2[T, N] = new ZsgTuple2(t, n) 34 | } 35 | } 36 | 37 | object RepMerge extends RepMerge 38 | -------------------------------------------------------------------------------- /modules/rep/src/test/scala/zsg/teskit/rep1/BooleanModel.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.rep1 2 | 3 | class BooleanModel(val isPrepared: Boolean) 4 | -------------------------------------------------------------------------------- /modules/rep/src/test/scala/zsg/teskit/rep1/Description.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.rep1 2 | 3 | class Description(val description: String) 4 | -------------------------------------------------------------------------------- /modules/rep/src/test/scala/zsg/teskit/rep1/Rep1.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.rep1 2 | 3 | import zsg.RepMerge._ 4 | import zsg.OptionRepTaker 5 | 6 | object Rep1 { 7 | def description(descript: String): Description = new Description(descript) 8 | def reverseBoolean: ReverseBoolean = ReverseBoolean.value 9 | val meta = StartRoute.value.merge(new BooleanModel(isPrepared = true)) 10 | val routeMeta = StartRoute.value 11 | 12 | class OptionTakerApply[Out] { 13 | def apply[In](i: In)(implicit taker: OptionRepTaker[In, Out]): Option[Out] = taker.take(i) 14 | } 15 | 16 | def takeOption[Out]: OptionTakerApply[Out] = new OptionTakerApply[Out] 17 | } 18 | -------------------------------------------------------------------------------- /modules/rep/src/test/scala/zsg/teskit/rep1/Rep1Test.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.rep1 2 | 3 | import zio.Console._ 4 | import zio.test._ 5 | import zio.test.Assertion._ 6 | import zio.test.environment._ 7 | import zsg.RepMerge._ 8 | 9 | object Rep1Test extends DefaultRunnableSpec { 10 | import Rep1._ 11 | 12 | override def spec = suite("Rep")( 13 | test("should auto lift in 1 meta model.") { 14 | val meta1 = routeMeta.merge(reverseBoolean).merge(description("iiiinnnn")) 15 | val meta2 = meta1.merge(description("bbbb")) 16 | val meta3 = meta2.merge(reverseBoolean) 17 | 18 | val assert5 = assert(takeOption[Description](meta3).get.description)(equalTo("iiiinnnn")) 19 | val assert6 = !assert(takeOption[BooleanModel](meta3))(equalTo(Option(new BooleanModel(true)))) 20 | val assert7 = assert(takeOption[BooleanModel](meta3))(equalTo(Option.empty)) 21 | 22 | assert5 && assert6 && assert7 23 | }, 24 | test("should auto lift in 2 meta model.") { 25 | val meta1 = meta.merge(description("iiiinnnn")) 26 | val meta2 = meta1.merge(description("bbbb")) 27 | val meta3 = meta2.merge(reverseBoolean) 28 | 29 | val assert1 = assert(takeOption[Description](meta3).get.description)(equalTo("iiiinnnn")) 30 | 31 | assert1 32 | } 33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /modules/rep/src/test/scala/zsg/teskit/rep1/ReverseBoolean.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.rep1 2 | 3 | class ReverseBoolean 4 | 5 | object ReverseBoolean { 6 | val value: ReverseBoolean = new ReverseBoolean 7 | } 8 | -------------------------------------------------------------------------------- /modules/rep/src/test/scala/zsg/teskit/rep1/RouteModel.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.rep1 2 | 3 | class StartRoute 4 | 5 | object StartRoute { 6 | val value: StartRoute = new StartRoute 7 | } 8 | 9 | class RouteModel(val description: String) 10 | -------------------------------------------------------------------------------- /modules/rep/version.sbt: -------------------------------------------------------------------------------- 1 | CommonSettings.projectVersionSetting 2 | name := "zsg-rep" 3 | -------------------------------------------------------------------------------- /modules/scala-tuple/build.sbt: -------------------------------------------------------------------------------- 1 | ZsgSettings.settings.dottyVersion 2 | CommonSettings.settings 3 | 4 | libraryDependencies ++= Dependencies.zioTest 5 | libraryDependencies += Dependencies.scalaCollectionCompat % Test 6 | 7 | scalafmtOnCompile := true 8 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/main/scala-3/zsg/scala/tuple/Tuple23Plus.scala: -------------------------------------------------------------------------------- 1 | package zsg.scala.tuple 2 | import zsg._ 3 | 4 | type Tuple23TypeHList[Item <: TypeHList, I1 <: TypeHList] <: TypeHList = (Item, I1) match { 5 | case (TypeZero, TypeZero) => TypeZero 6 | case (TypePositive[head1, tail1], TypePositive[head2, tail2]) => 7 | TypePositive[head1 *: head2, Tuple23TypeHList[tail1, tail2]] 8 | } 9 | 10 | object Tuple23Plus { 11 | 12 | lazy val tupeXXLPlusImpl: Plus[TypeHList, TypeHList, TypeHList] = new Plus[TypeHList, TypeHList, TypeHList] { 13 | override def takeHead(u: TypeHead[TypeHList]): TypeHead[TypeHList] = { 14 | val z = u.asInstanceOf[*:[_, _]] 15 | z.head.asInstanceOf[TypeHead[TypeHList]] 16 | } 17 | override def takeTail(u: TypeHead[TypeHList]): TypeHead[TypeHList] = { 18 | val z = u.asInstanceOf[*:[_, _]] 19 | z.tail.asInstanceOf[TypeHead[TypeHList]] 20 | } 21 | override def plus(x: TypeHead[TypeHList], u: TypeHead[TypeHList]): TypeHead[TypeHList] = { 22 | val y = u.asInstanceOf[Tuple] 23 | (x *: y).asInstanceOf[TypeHead[TypeHList]] 24 | } 25 | override def tail: Plus[TypeTail[TypeHList], TypeTail[TypeHList], TypeTail[TypeHList]] = 26 | tupeXXLPlusImpl.asInstanceOf[Plus[TypeTail[TypeHList], TypeTail[TypeHList], TypeTail[TypeHList]]] 27 | } 28 | 29 | def tupleXXLPlus[X <: TypeHList, Y <: TypeHList]: Plus[X, Y, Tuple23TypeHList[X, Y]] = 30 | tupeXXLPlusImpl.asInstanceOf[Plus[X, Y, Tuple23TypeHList[X, Y]]] 31 | 32 | } 33 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/main/scala-3/zsg/scala/tuple/TupleHelper23.scala: -------------------------------------------------------------------------------- 1 | package zsg.scala.tuple 2 | import zsg._ 3 | 4 | trait TupleHelper23 { 5 | 6 | given [T <: Context, Boot1, Target1 <: TypeHList, Boot2 <: Tuple, Target2 <: TypeHList](using 7 | v1: Application[T, Boot1, Target1], 8 | v2: Application[T, Boot2, Target2] 9 | ): Application[T, Boot1 *: Boot2, Tuple23TypeHList[Target1, Target2]] = context => 10 | context.append(v1.application(context), v2.application(context))(Tuple23Plus.tupleXXLPlus) 11 | 12 | } 13 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/test/scala-2/zsg/testkit/tuple/reverse/ReverseTupleToString.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.tuple.reverse 2 | 3 | import zsg.{Application, Context, Plus, TypeAlias, TypeFunction, TypeHList} 4 | 5 | import scala.collection.compat._ 6 | 7 | trait ReverseTupleEncoder[T] { 8 | self => 9 | def body(t: List[String], i: T): List[String] 10 | def stringBody(i: T): String 11 | } 12 | 13 | class ReverseTupleEncFun extends TypeFunction { 14 | override type H[T <: TypeHList] = ReverseTupleEncoder[T#Head] 15 | } 16 | 17 | object ReverseScalaTupleContext extends Context[ReverseTupleEncFun] { 18 | override def append[X <: TypeHList, Y <: TypeHList, Z <: TypeHList](x: ReverseTupleEncoder[X#Head], y: ReverseTupleEncoder[Y#Head])( 19 | plus: Plus[X, Y, Z] 20 | ): ReverseTupleEncoder[Z#Head] = new ReverseTupleEncoder[Z#Head] { 21 | override def body(t: List[String], i: Z#Head): List[String] = { 22 | val x1 = plus.takeHead(i) 23 | val y1 = plus.takeTail(i) 24 | y.body(x.body(t, x1), y1) 25 | } 26 | override def stringBody(i: Z#Head): String = "" 27 | } 28 | } 29 | 30 | object reverseTuple { 31 | def asString[T, H <: TypeHList]( 32 | x: T 33 | )(implicit ii: Application[ReverseTupleEncFun, T, H { type Head = T }]): String = { 34 | val con = ii.application(ReverseScalaTupleContext) 35 | s"[${con.body(List.empty, x).mkString("(", ",", ")")}]" 36 | } 37 | 38 | def commonAsString(t: Product): String = { 39 | def toList(pro: Product): List[Any] = pro.productIterator.to(List).flatMap { 40 | case n: Product => toList(n) 41 | case i => List(i) 42 | } 43 | s"[${toList(t).reverse.mkString("(", ",", ")")}]" 44 | } 45 | } 46 | 47 | object ReverseAppendTuple { 48 | implicit val reverseTupleImplicit1: ReverseTupleEncoder[String] = new ReverseTupleEncoder[String] { 49 | override def body(t: List[String], i: String): List[String] = i :: t 50 | override def stringBody(i: String): String = i 51 | } 52 | 53 | implicit val reverseTupleImplicit12: ReverseTupleEncoder[Int] = new ReverseTupleEncoder[Int] { 54 | override def body(t: List[String], i: Int): List[String] = String.valueOf(i) :: t 55 | override def stringBody(i: Int): String = String.valueOf(i) 56 | } 57 | 58 | implicit val reverseTupleImplicit3: ReverseTupleEncoder[Long] = new ReverseTupleEncoder[Long] { 59 | override def body(t: List[String], i: Long): List[String] = String.valueOf(i) :: t 60 | override def stringBody(i: Long): String = String.valueOf(i) 61 | } 62 | 63 | implicit def reverseApplicationImplicit[T](implicit 64 | t1: ReverseTupleEncoder[T] 65 | ): Application[ReverseTupleEncFun, T, TypeAlias.TypeHList1[T]] = 66 | new Application[ReverseTupleEncFun, T, TypeAlias.TypeHList1[T]] { 67 | override def application(context: Context[ReverseTupleEncFun]): ReverseTupleEncoder[T] = t1 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/test/scala-2/zsg/testkit/tuple/reverse/ReverseTupleToStringTest.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.tuple.reverse 2 | 3 | import zio.Console._ 4 | import zio.test._ 5 | import zio.test.Assertion._ 6 | import zio.test.environment._ 7 | 8 | object ReverseTupleToStringTest extends DefaultRunnableSpec { 9 | 10 | import ReverseAppendTuple._ 11 | import zsg.scala.tuple.TupleHelper._ 12 | 13 | override def spec = suite("Tuple Mapper")(test("auto map to string") { 14 | val assert1 = assert(reverseTuple.asString(ReverseTupleData.i10))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i10))) 15 | val assert2 = assert(reverseTuple.asString(ReverseTupleData.i11))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i11))) 16 | val assert3 = assert(reverseTuple.asString(ReverseTupleData.i12))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i12))) 17 | val assert4 = assert(reverseTuple.asString(ReverseTupleData.i13))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i13))) 18 | val assert5 = assert(reverseTuple.asString(ReverseTupleData.i14))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i14))) 19 | val assert6 = assert(reverseTuple.asString(ReverseTupleData.i15))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i15))) 20 | val assert7 = assert(reverseTuple.asString(ReverseTupleData.i16))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i16))) 21 | val assert8 = assert(reverseTuple.asString(ReverseTupleData.i17))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i17))) 22 | val assert9 = assert(reverseTuple.asString(ReverseTupleData.i18))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i18))) 23 | val assert10 = assert(reverseTuple.asString(ReverseTupleData.i19))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i19))) 24 | val assert11 = assert(reverseTuple.asString(ReverseTupleData.i20))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i20))) 25 | val assert12 = assert(reverseTuple.asString(ReverseTupleData.i21))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i21))) 26 | val assert13 = assert(reverseTuple.asString(ReverseTupleData.i22))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i22))) 27 | assert1 && assert2 && assert3 && assert4 && assert5 && assert6 && assert7 && assert8 && assert9 && assert10 && assert11 && assert12 && assert13 28 | }) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/test/scala-3/zsg/testkit/tuple/Scala3TupleData.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.tuple 2 | 3 | object Scala3TupleData { 4 | 5 | val i27 = ( 6 | "i1", 7 | "i2", 8 | 3, 9 | 4, 10 | 5L, 11 | "i6", 12 | "i7", 13 | "i8", 14 | 9, 15 | 10, 16 | 11, 17 | 12, 18 | 13, 19 | (1, 2, "i3", "i4", "i5", "i6", 7, ("i4"), 9), 20 | 15, 21 | 16, 22 | "i17", 23 | "i18", 24 | 19, 25 | 20, 26 | 21L, 27 | 22, 28 | 23, 29 | 24, 30 | "i25", 31 | 26, 32 | "i27" 33 | ) 34 | val i22 = ( 35 | "i1", 36 | "i2", 37 | 3, 38 | 4, 39 | 5L, 40 | "i6", 41 | "i7", 42 | "i8", 43 | 9, 44 | 10, 45 | 11, 46 | 12, 47 | 13, 48 | (1, 2, "i3", "i4", "i5", "i6", 7, 8, 9, 10L), 49 | 15, 50 | 16, 51 | "i17", 52 | "i18", 53 | 19, 54 | 20, 55 | 21L, 56 | 22 57 | ) 58 | 59 | } 60 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/test/scala-3/zsg/testkit/tuple/TupleToStringTest.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.tuple 2 | 3 | import zio.Console._ 4 | import zio.test._ 5 | import zio.test.Assertion._ 6 | import zio.test.environment._ 7 | 8 | object TupleToStringTest1 extends DefaultRunnableSpec { 9 | 10 | import AppendTuple.given 11 | import zsg.scala.tuple.TupleHelper.given 12 | 13 | override def spec = suite("Tuple Mapper 2")( 14 | test("auto map to string 1") { 15 | val assert1 = assert(tuple.asString(TupleData.i10))(equalTo(tuple.commonAsString(TupleData.i10))) 16 | val assert2 = assert(tuple.asString(TupleData.i11))(equalTo(tuple.commonAsString(TupleData.i11))) 17 | val assert3 = assert(tuple.asString(TupleData.i12))(equalTo(tuple.commonAsString(TupleData.i12))) 18 | val assert4 = assert(tuple.asString(TupleData.i13))(equalTo(tuple.commonAsString(TupleData.i13))) 19 | val assert5 = assert(tuple.asString(TupleData.i14))(equalTo(tuple.commonAsString(TupleData.i14))) 20 | val assert6 = assert(tuple.asString(TupleData.i15))(equalTo(tuple.commonAsString(TupleData.i15))) 21 | val assert7 = assert(tuple.asString(TupleData.i16))(equalTo(tuple.commonAsString(TupleData.i16))) 22 | val assert8 = assert(tuple.asString(TupleData.i17))(equalTo(tuple.commonAsString(TupleData.i17))) 23 | val assert9 = assert(tuple.asString(TupleData.i18))(equalTo(tuple.commonAsString(TupleData.i18))) 24 | val assert10 = assert(tuple.asString(TupleData.i19))(equalTo(tuple.commonAsString(TupleData.i19))) 25 | val assert11 = assert(tuple.asString(TupleData.i20))(equalTo(tuple.commonAsString(TupleData.i20))) 26 | val assert12 = assert(tuple.asString(TupleData.i21))(equalTo(tuple.commonAsString(TupleData.i21))) 27 | val assert13 = assert(tuple.asString(TupleData.i22))(equalTo(tuple.commonAsString(TupleData.i22))) 28 | val assert14 = assert(tuple.asString(Scala3TupleData.i22))(equalTo(tuple.commonAsString(Scala3TupleData.i22))) 29 | val assert15 = assert(tuple.asString(Scala3TupleData.i27))(equalTo(tuple.commonAsString(Scala3TupleData.i27))) 30 | assert1 && assert2 && assert3 && assert4 && assert5 && assert6 && assert7 && assert8 && assert9 && assert10 && assert11 && assert12 && assert13 31 | } 32 | ) 33 | 34 | } 35 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/test/scala-3/zsg/testkit/tuple/TupleToStringTest2.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.tuple 2 | 3 | import zio.Console._ 4 | import zio.test._ 5 | import zio.test.Assertion._ 6 | import zio.test.environment._ 7 | 8 | object TupleToStringTest2 extends DefaultRunnableSpec { 9 | 10 | import AppendTuple.given 11 | import zsg.scala.tuple.TupleHelper.given 12 | 13 | override def spec = suite("Tuple Mapper 2")( 14 | test("auto map to string 2") { 15 | val assert11 = assert(tuple.asString(TupleData.i20))(equalTo(tuple.commonAsString(TupleData.i20))) 16 | val assert12 = assert(tuple.asString(TupleData.i21))(equalTo(tuple.commonAsString(TupleData.i21))) 17 | val assert13 = assert(tuple.asString(TupleData.i22))(equalTo(tuple.commonAsString(TupleData.i22))) 18 | val assert14 = assert(tuple.asString(Scala3TupleData.i27))(equalTo(tuple.commonAsString(Scala3TupleData.i27))) 19 | assert11 && assert12 && assert13 20 | } 21 | ) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/test/scala-3/zsg/testkit/tuple/TupleToStringTest3.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.tuple 2 | 3 | import zio.Console._ 4 | import zio.test._ 5 | import zio.test.Assertion._ 6 | import zio.test.environment._ 7 | 8 | object TupleToStringTest3 extends DefaultRunnableSpec { 9 | 10 | import AppendTuple.given 11 | import zsg.scala.tuple.TupleHelper.given 12 | 13 | override def spec = suite("Tuple Mapper 2")( 14 | test("auto map to string 3") { 15 | val assert1 = assert( 16 | tuple.gen[(String, String, Int, Int, Long, String, String, String, Int, Int)].fromString(tuple.commonAsString1(TupleData.i10)) 17 | )(equalTo(TupleData.i10)) 18 | val assert2 = assert( 19 | tuple.gen[(String, String, Int, Int, Long, String, String, String, Int, Int, Int)].fromString(tuple.commonAsString1(TupleData.i11)) 20 | )(equalTo(TupleData.i11)) 21 | val assert3 = 22 | assert( 23 | tuple 24 | .gen[(String, String, Int, Int, Long, String, String, String, Int, Int, Int, Int)] 25 | .fromString(tuple.commonAsString1(TupleData.i12)) 26 | )(equalTo(TupleData.i12)) 27 | val assert4 = 28 | assert( 29 | tuple 30 | .gen[(String, String, Int, Int, Long, String, String, String, Int, Int, Int, Int, Int)] 31 | .fromString(tuple.commonAsString1(TupleData.i13)) 32 | )(equalTo(TupleData.i13)) 33 | val assert5 = assert( 34 | tuple 35 | .gen[(String, String, Int, Int, Long, String, String, String, Int, Int, Int, Int, Int, (Int, Int))] 36 | .fromString( 37 | tuple.commonAsString1(TupleData.i14) 38 | ) 39 | )(equalTo(TupleData.i14)) 40 | val assert6 = 41 | assert( 42 | tuple 43 | .gen[(String, String, Int, Int, Long, String, String, String, Int, Int, Int, Int, Int, (Int, Int, String), Int)] 44 | .fromString(tuple.commonAsString1(TupleData.i15)) 45 | )(equalTo(TupleData.i15)) 46 | val assert7 = 47 | assert( 48 | tuple 49 | .gen[(String, String, Int, Int, Long, String, String, String, Int, Int, Int, Int, (Int, Int, String, String), Int, Int, Int)] 50 | .fromString(tuple.commonAsString1(TupleData.i16)) 51 | )(equalTo(TupleData.i16)) 52 | assert1 && assert2 && assert3 && assert4 && assert5 && assert6 && assert7 53 | } 54 | ) 55 | 56 | } 57 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/test/scala-3/zsg/testkit/tuple/reverse/ReverseTupleToString.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.tuple.reverse 2 | 3 | import zsg._ 4 | 5 | trait ReverseTupleEncoder[T] { 6 | self => 7 | def body(t: List[String], i: T): List[String] 8 | def stringBody(i: T): String 9 | } 10 | 11 | type TupleEncFun[T <: TypeHList] = ReverseTupleEncoder[TakeHead1[T]] 12 | 13 | class ReverseScalaTupleContext extends Context { 14 | 15 | override type T[H <: TypeHList] = TupleEncFun[H] 16 | 17 | override def append[X <: TypeHList, Y <: TypeHList, Z <: TypeHList]( 18 | x: ReverseTupleEncoder[TakeHead1[X]], 19 | y: ReverseTupleEncoder[TakeHead1[Y]] 20 | )(p: Plus[X, Y, Z]): ReverseTupleEncoder[TakeHead1[Z]] = { 21 | new ReverseTupleEncoder[TakeHead1[Z]] { 22 | override def body(t: List[String], i: TakeHead1[Z]): List[String] = { 23 | val x1 = p.takeHead(i) 24 | val y1 = p.takeTail(i) 25 | y.body(x.body(t, x1), y1) 26 | } 27 | override def stringBody(i: TakeHead1[Z]): String = "" 28 | } 29 | } 30 | 31 | } 32 | 33 | object ReverseScalaTupleContext { 34 | val value: ReverseScalaTupleContext = new ReverseScalaTupleContext 35 | } 36 | 37 | object reverseTuple { 38 | def commonAsString(t: Product): String = { 39 | def toList(pro: Product): List[Any] = pro.productIterator.to(List).reverse.flatMap { 40 | case n: Product => toList(n) 41 | case i => List(i) 42 | } 43 | s"[${toList(t).mkString("(", ",", ")")}]" 44 | } 45 | 46 | inline def asString[T, H <: TypeHList](x: T)(using inline ii: Application[ReverseScalaTupleContext, T, H]): String = { 47 | val n1 = ii.application(ReverseScalaTupleContext.value) 48 | s"[${n1.body(List.empty, x.asInstanceOf[TakeHead1[H]]).mkString("(", ",", ")")}]" 49 | } 50 | } 51 | 52 | object ReverseAppendTuple { 53 | inline given ReverseTupleEncoder[String] with { 54 | override def body(t: List[String], i: String): List[String] = i :: t 55 | override def stringBody(i: String): String = i 56 | } 57 | 58 | inline given ReverseTupleEncoder[Int] with { 59 | override def body(t: List[String], i: Int): List[String] = String.valueOf(i) :: t 60 | override def stringBody(i: Int): String = String.valueOf(i) 61 | } 62 | 63 | inline given ReverseTupleEncoder[Long] with { 64 | override def body(t: List[String], i: Long): List[String] = String.valueOf(i) :: t 65 | override def stringBody(i: Long): String = String.valueOf(i) 66 | } 67 | 68 | given [T](using ii: ReverseTupleEncoder[T]): Application[ReverseScalaTupleContext, T, TypePositive[T, TypeZero]] = 69 | context => implicitly 70 | 71 | } 72 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/test/scala-3/zsg/testkit/tuple/reverse/ReverseTupleToStringTest.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.tuple.reverse 2 | 3 | import zio.Console._ 4 | import zio.test._ 5 | import zio.test.Assertion._ 6 | import zio.test.environment._ 7 | import zsg.testkit.tuple.Scala3TupleData 8 | 9 | object ReverseTupleToStringTest extends DefaultRunnableSpec { 10 | 11 | import ReverseAppendTuple.given 12 | import zsg.scala.tuple.TupleHelper.given 13 | 14 | override def spec = suite("Tuple Mapper")(test("auto map to string") { 15 | val assert1 = assert(reverseTuple.asString(ReverseTupleData.i10))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i10))) 16 | val assert2 = assert(reverseTuple.asString(ReverseTupleData.i11))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i11))) 17 | val assert3 = assert(reverseTuple.asString(ReverseTupleData.i12))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i12))) 18 | val assert4 = assert(reverseTuple.asString(ReverseTupleData.i13))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i13))) 19 | val assert5 = assert(reverseTuple.asString(ReverseTupleData.i14))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i14))) 20 | val assert6 = assert(reverseTuple.asString(ReverseTupleData.i15))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i15))) 21 | val assert7 = assert(reverseTuple.asString(ReverseTupleData.i16))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i16))) 22 | val assert8 = assert(reverseTuple.asString(ReverseTupleData.i17))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i17))) 23 | val assert9 = assert(reverseTuple.asString(ReverseTupleData.i18))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i18))) 24 | val assert10 = assert(reverseTuple.asString(ReverseTupleData.i19))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i19))) 25 | val assert11 = assert(reverseTuple.asString(ReverseTupleData.i20))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i20))) 26 | val assert12 = assert(reverseTuple.asString(ReverseTupleData.i21))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i21))) 27 | val assert13 = assert(reverseTuple.asString(ReverseTupleData.i22))(equalTo(reverseTuple.commonAsString(ReverseTupleData.i22))) 28 | val assert14 = assert(reverseTuple.asString(Scala3TupleData.i22))(equalTo(reverseTuple.commonAsString(Scala3TupleData.i22))) 29 | val assert15 = assert(reverseTuple.asString(Scala3TupleData.i27))(equalTo(reverseTuple.commonAsString(Scala3TupleData.i27))) 30 | assert1 && assert2 && assert3 && assert4 && assert5 && assert6 && assert7 && assert8 && assert9 && assert10 && assert11 && assert12 && assert13 && assert14 && assert15 31 | }) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/test/scala/zsg/testkit/tuple/TupleData.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.tuple 2 | 3 | object TupleData { 4 | 5 | val i10 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10) 6 | val i11 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11) 7 | val i12 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12) 8 | val i13 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12, 13) 9 | val i14 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12, 13, (1, 2)) 10 | val i15 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12, 13, (1, 2, "i3"), 15) 11 | val i16 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12, (1, 2, "i3", "i4"), 14, 15, 16) 12 | val i17 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12, (1, 2, "i3", "i4", "i5"), 14, 15, 16, "i17") 13 | val i18 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, (1, 2, "i3", "i4", "i5", "i6"), 13, 14, 15, 16, "i17", "i18") 14 | val i19 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, (1, 2, "i3", "i4", "i5", "i6", 7), 11, 12, 13, 14, 15, 16, "i17", "i18", 19) 15 | val i20 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, (1, 2, "i3", "i4", "i5", "i6", 7, 8L), 13, 14, 15, 16, "i17", "i18", 19, 20) 16 | val i21 = ( 17 | "i1", 18 | "i2", 19 | 3, 20 | 4, 21 | 5L, 22 | "i6", 23 | "i7", 24 | "i8", 25 | 9, 26 | 10, 27 | 11, 28 | 12, 29 | 13, 30 | (1, 2, "i3", "i4", "i5", "i6", 7, ("i4"), 9), 31 | 15, 32 | 16, 33 | "i17", 34 | "i18", 35 | 19, 36 | 20, 37 | 21L 38 | ) 39 | val i22 = ( 40 | "i1", 41 | "i2", 42 | 3, 43 | 4, 44 | 5L, 45 | "i6", 46 | "i7", 47 | "i8", 48 | 9, 49 | 10, 50 | 11, 51 | 12, 52 | 13, 53 | (1, 2, "i3", "i4", "i5", "i6", 7, 8, 9, 10L), 54 | 15, 55 | 16, 56 | "i17", 57 | "i18", 58 | 19, 59 | 20, 60 | 21L, 61 | 22 62 | ) 63 | 64 | } 65 | -------------------------------------------------------------------------------- /modules/scala-tuple/src/test/scala/zsg/testkit/tuple/reverse/ReverseTupleData.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.tuple.reverse 2 | 3 | object ReverseTupleData { 4 | 5 | val i10 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10) 6 | val i11 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11) 7 | val i12 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12) 8 | val i13 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12, 13) 9 | val i14 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12, 13, (1, 2)) 10 | val i15 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12, 13, (1, 2, "i3"), 15) 11 | val i16 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12, (1, 2, "i3", "i4"), 14, 15, 16) 12 | val i17 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, 12, (1, 2, "i3", "i4", "i5"), 14, 15, 16, "i17") 13 | val i18 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, (1, 2, "i3", "i4", "i5", "i6"), 13, 14, 15, 16, "i17", "i18") 14 | val i19 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, (1, 2, "i3", "i4", "i5", "i6", 7), 11, 12, 13, 14, 15, 16, "i17", "i18", 19) 15 | val i20 = ("i1", "i2", 3, 4, 5L, "i6", "i7", "i8", 9, 10, 11, (1, 2, "i3", "i4", "i5", "i6", 7, 8L), 13, 14, 15, 16, "i17", "i18", 19, 20) 16 | val i21 = ( 17 | "i1", 18 | "i2", 19 | 3, 20 | 4, 21 | 5L, 22 | "i6", 23 | "i7", 24 | "i8", 25 | 9, 26 | 10, 27 | 11, 28 | 12, 29 | 13, 30 | (1, 2, "i3", "i4", "i5", "i6", 7, ("i4", i17), 9), 31 | 15, 32 | 16, 33 | "i17", 34 | "i18", 35 | 19, 36 | 20, 37 | 21L 38 | ) 39 | val i22 = ( 40 | "i1", 41 | "i2", 42 | 3, 43 | 4, 44 | 5L, 45 | "i6", 46 | "i7", 47 | "i8", 48 | 9, 49 | 10, 50 | 11, 51 | 12, 52 | 13, 53 | (1, 2, "i3", "i4", "i5", "i6", 7, 8, 9, 10L), 54 | 15, 55 | 16, 56 | "i17", 57 | "i18", 58 | 19, 59 | 20, 60 | 21L, 61 | 22 62 | ) 63 | 64 | } 65 | -------------------------------------------------------------------------------- /modules/scala-tuple/version.sbt: -------------------------------------------------------------------------------- 1 | CommonSettings.projectVersionSetting 2 | name := "zsg-scala-tuple" 3 | -------------------------------------------------------------------------------- /modules/testkit/build.sbt: -------------------------------------------------------------------------------- 1 | ZsgSettings.settings.scalaVersion 2 | CommonSettings.settings 3 | 4 | libraryDependencies ++= Dependencies.circeDependencies(scalaVersion.value) 5 | //libraryDependencies ++= Dependices.upickleDependencies 6 | libraryDependencies ++= Dependencies.zioTest 7 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2.11/CirceVersionCompat.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe 2 | 3 | import io.circe.ObjectEncoder 4 | 5 | object CirceVersionCompat { 6 | 7 | type JsonObjectEncoder[T] = ObjectEncoder[T] 8 | @inline val JsonObjectEncoder = ObjectEncoder 9 | 10 | } 11 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2.12/CirceVersionCompat.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe 2 | 3 | import io.circe.Encoder 4 | 5 | object CirceVersionCompat { 6 | 7 | type JsonObjectEncoder[T] = Encoder.AsObject[T] 8 | @inline val JsonObjectEncoder = Encoder.AsObject 9 | 10 | } 11 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2.13/CirceVersionCompat.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe 2 | 3 | import io.circe.Encoder 4 | 5 | object CirceVersionCompat { 6 | 7 | type JsonObjectEncoder[T] = Encoder.AsObject[T] 8 | @inline val JsonObjectEncoder = Encoder.AsObject 9 | 10 | } 11 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2/zsg/testkit/circe/ACirce.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe 2 | 3 | import zsg.macros.single.deficient.AsunaTupleApply 4 | import zsg.{Application, TagMerge2, TypeHList} 5 | import zsg.macros.single.{ 6 | ZsgDefaultValue, 7 | ZsgGeneric, 8 | ZsgGetterGeneric, 9 | ZsgLabelledGeneric, 10 | ZsgLabelledTypeGeneric, 11 | ZsgSealedClassGeneric, 12 | ZsgSealedGeneric, 13 | ZsgSealedLabelledGeneric, 14 | ZsgSetterGeneric 15 | } 16 | import io.circe.{Decoder, Encoder, JsonObject} 17 | 18 | object ACirce { 19 | 20 | final def mapTupleEncoder[Model, PreTuple <: TupleType, TupleType]( 21 | ll: AsunaTupleApply[Model, PreTuple], 22 | objectEncoder: Encoder[TupleType] 23 | ): Encoder[Model] = objectEncoder.contramap(ll.toTuple) 24 | 25 | final def encodeCaseClass[H, R, N, I, P <: TypeHList](implicit 26 | ll: ZsgGeneric.Aux[H, R], 27 | nm: ZsgLabelledTypeGeneric.Aux[H, N], 28 | merge: TagMerge2.Aux[R, N, I], 29 | app: Application[encoder.JsonObjectFunc, I, P], 30 | cv2: ZsgGetterGeneric[H, P#Tail#Head] 31 | ): CirceVersionCompat.JsonObjectEncoder[H] = { 32 | val applicationEncoder = app.application(encoder.ZsgJsonObjectContext) 33 | CirceVersionCompat.JsonObjectEncoder.instance { o: H => 34 | JsonObject.fromIterable(applicationEncoder.appendField(cv2.getter(o), List.empty)) 35 | } 36 | } 37 | 38 | final def encodeCaseObject[T]: CirceVersionCompat.JsonObjectEncoder[T] = 39 | CirceVersionCompat.JsonObjectEncoder.instance(_ => JsonObject.empty) 40 | 41 | final def encodeSealed[P, R, T <: TypeHList](implicit 42 | ll: ZsgSealedGeneric.Aux[P, R], 43 | app: Application[encoder.SealedTraitSelector[P], R, T], 44 | cv1: ZsgSealedLabelledGeneric[P, T#Tail#Head], 45 | cv2: ZsgSealedClassGeneric[P, T#Head] 46 | ): CirceVersionCompat.JsonObjectEncoder[P] = { 47 | val name1 = cv1.names 48 | val name2 = cv2.names 49 | val applicationEncoder = app.application(encoder.ZsgSealedContext.c[P]) 50 | CirceVersionCompat.JsonObjectEncoder.instance { o: P => JsonObject.fromIterable(applicationEncoder.p(o, name2, name1)) } 51 | } 52 | 53 | def decodeCaseClass[T, R, M <: TypeHList](implicit 54 | ll: ZsgGeneric.Aux[T, R], 55 | app: Application[decoder.JsonDecoderFunc, R, M], 56 | cv1: ZsgLabelledGeneric[T, M#Tail#Head], 57 | cv3: ZsgSetterGeneric[T, M#Head], 58 | cv4: ZsgDefaultValue#ModelType[T]#GenericType[M#Tail#Tail#Head] 59 | ): Decoder[T] = app.application(decoder.ZsgDecoderContext).to(cv1.names, cv4.defaultValues).map(mm => cv3.setter(mm)) 60 | 61 | def decodeSealed[H, R, Nam <: TypeHList](implicit 62 | ll: ZsgSealedGeneric.Aux[H, R], 63 | app: Application[decoder.SealedTraitSelector[H], R, Nam], 64 | cv1: ZsgSealedLabelledGeneric[H, Nam#Tail#Head] 65 | ): Decoder[H] = { 66 | val names = cv1.names 67 | app.application(decoder.ZsgSealedContext.c[H]).to(names) 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2/zsg/testkit/circe/decoder/JsonDecoderPro.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.decoder 2 | 3 | import zsg.macros.single.DefaultValue 4 | import zsg.macros.ByNameImplicit 5 | import io.circe._ 6 | import zsg.{Application, Context, PropertyTag, TypeAlias, TypeFunction, TypeHList} 7 | 8 | trait JsonDecoderPro[T, II, D] extends Any { 9 | def to(name: II, defaultValue: D): Decoder[T] 10 | } 11 | 12 | class JsonDecoderFunc extends TypeFunction { 13 | override type H[T <: TypeHList] = JsonDecoderPro[T#Head, T#Tail#Head, T#Tail#Tail#Head] 14 | } 15 | 16 | object JsonDecoderFunc { 17 | implicit def implicit1[T1](implicit 18 | dd: ByNameImplicit[Decoder[T1]] 19 | ): Application[JsonDecoderFunc, PropertyTag[T1], TypeAlias.TypeHList3[T1, String, DefaultValue[T1]]] = 20 | new Application[JsonDecoderFunc, PropertyTag[T1], TypeAlias.TypeHList3[T1, String, DefaultValue[T1]]] { 21 | override def application(context: Context[JsonDecoderFunc]): JsonDecoderPro[T1, String, DefaultValue[T1]] = 22 | new JsonDecoderPro[T1, String, DefaultValue[T1]] { 23 | override def to(name: String, defaultValue: DefaultValue[T1]): Decoder[T1] = { 24 | Decoder.instance { j => defaultValue.value.map(s => Right(s)).getOrElse(j.get(name)(dd.value)) } 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2/zsg/testkit/circe/decoder/SealedTraitSelector.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.decoder 2 | 3 | import zsg.macros.ByNameImplicit 4 | import zsg.macros.single.SealedTag 5 | import io.circe.Decoder 6 | import zsg.{Application, Context, TypeAlias, TypeFunction, TypeHList} 7 | 8 | class SealedTraitSelector[P] extends TypeFunction { 9 | override type H[T <: TypeHList] = JsonDecoder[P, T#Head, T#Tail#Head] 10 | } 11 | 12 | object SealedTraitSelector { 13 | implicit def implicit1[P, S <: P](implicit 14 | t: ByNameImplicit[Decoder[S]] 15 | ): Application[SealedTraitSelector[P], SealedTag[S], TypeAlias.TypeHList2[SealedTag[S], String]] = 16 | new Application[SealedTraitSelector[P], SealedTag[S], TypeAlias.TypeHList2[SealedTag[S], String]] { 17 | override def application( 18 | context: Context[SealedTraitSelector[P]] 19 | ): SealedTraitSelector[P]#H[TypeAlias.TypeHList2[SealedTag[S], String]] = 20 | new JsonDecoder[P, SealedTag[S], String] { 21 | override def to(name: String): Decoder[P] = { 22 | Decoder.instance(j => j.get(name)(t.value): Decoder.Result[S]) 23 | } 24 | } 25 | } 26 | } 27 | 28 | trait JsonDecoder[P, PU, II] { 29 | def to(name: II): Decoder[P] 30 | } 31 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2/zsg/testkit/circe/decoder/ZsgDecoderContext.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.decoder 2 | 3 | import zsg.{Context, Plus, TypeHList} 4 | import io.circe.Decoder 5 | 6 | object ZsgDecoderContext extends Context[JsonDecoderFunc] { 7 | override def append[X <: TypeHList, Y <: TypeHList, Z <: TypeHList]( 8 | x: JsonDecoderPro[X#Head, X#Tail#Head, X#Tail#Tail#Head], 9 | y: JsonDecoderPro[Y#Head, Y#Tail#Head, Y#Tail#Tail#Head] 10 | )( 11 | plus: Plus[X, Y, Z] 12 | ): JsonDecoderPro[Z#Head, Z#Tail#Head, Z#Tail#Tail#Head] = { 13 | new JsonDecoderPro[Z#Head, Z#Tail#Head, Z#Tail#Tail#Head] { 14 | override def to(name: Z#Tail#Head, defaultValue: Z#Tail#Tail#Head): Decoder[Z#Head] = { 15 | val xx1 = plus.tail.takeHead(name) 16 | val xx2 = plus.tail.tail.takeHead(defaultValue) 17 | val yy1 = plus.tail.takeTail(name) 18 | val yy2 = plus.tail.tail.takeTail(defaultValue) 19 | for { 20 | x1 <- x.to(xx1, xx2) 21 | y1 <- y.to(yy1, yy2) 22 | } yield plus.plus(x1, y1) 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2/zsg/testkit/circe/decoder/ZsgSealedContext.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.decoder 2 | 3 | import zsg.{Context, Plus, TypeHList} 4 | import io.circe.Decoder 5 | 6 | class ZsgSealedContext[P] extends Context[SealedTraitSelector[P]] { 7 | override def append[X <: TypeHList, Y <: TypeHList, Z <: TypeHList](x: SealedTraitSelector[P]#H[X], y: SealedTraitSelector[P]#H[Y])( 8 | plus: Plus[X, Y, Z] 9 | ): JsonDecoder[P, Z#Head, Z#Tail#Head] = { 10 | new JsonDecoder[P, Z#Head, Z#Tail#Head] { 11 | override def to(name: Z#Tail#Head): Decoder[P] = { 12 | val a1 = plus.tail.takeHead(name) 13 | val a2 = plus.tail.takeTail(name) 14 | val decoderX = x.to(a1) 15 | val decoderY = y.to(a2) 16 | decoderX.or(decoderY) 17 | } 18 | } 19 | } 20 | } 21 | 22 | object ZsgSealedContext { 23 | def c[H]: ZsgSealedContext[H] = new ZsgSealedContext[H] 24 | } 25 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2/zsg/testkit/circe/encoder/JsonObjectAppender.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.encoder 2 | 3 | import io.circe.{Encoder, Json} 4 | import zsg.{Application, Context, PropertyTag, TagMerge2, TypeAlias, TypeFunction, TypeHList} 5 | import zsg.macros.ByNameImplicit 6 | import zsg.macros.single.ColumnName 7 | import zsg.macros.utils.GenericColumnName 8 | 9 | abstract class JsonObjectAppender[NameTag, T] { 10 | def appendField(tt: T, m: List[(String, Json)]): List[(String, Json)] 11 | } 12 | 13 | class JsonObjectFunc extends TypeFunction { 14 | override type H[T <: TypeHList] = JsonObjectAppender[T#Head, T#Tail#Head] 15 | } 16 | 17 | object JsonObjectFunc { 18 | implicit def implicit1[T1 <: String, T2](implicit 19 | t: ByNameImplicit[Encoder[T2]], 20 | n: GenericColumnName[T1] 21 | ): Application[JsonObjectFunc, TagMerge2[PropertyTag[T2], ColumnName[T1]], TypeAlias.TypeHList2[ColumnName[ 22 | T1 23 | ], T2]] = 24 | new Application[ 25 | JsonObjectFunc, 26 | TagMerge2[PropertyTag[T2], ColumnName[T1]], 27 | TypeAlias.TypeHList2[ColumnName[T1], T2] 28 | ] { 29 | override def application(context: Context[JsonObjectFunc]): JsonObjectAppender[ColumnName[T1], T2] = 30 | new JsonObjectAppender[ColumnName[T1], T2] { 31 | override def appendField(tt: T2, m: List[(String, Json)]): List[(String, Json)] = (n.value, t.value(tt)) :: m 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2/zsg/testkit/circe/encoder/SealedTraitSelector.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.encoder 2 | 3 | import zsg.macros.ByNameImplicit 4 | import zsg.macros.single.SealedTag 5 | import io.circe.{Encoder, Json} 6 | import zsg.{Application, Context, TypeAlias, TypeFunction, TypeHList} 7 | 8 | class SealedTraitSelector[H1] extends TypeFunction { 9 | override type H[T <: TypeHList] = JsonEncoder[H1, T#Head, T#Tail#Head] 10 | } 11 | 12 | object SealedTraitSelector { 13 | implicit def implicit1[P, S](implicit 14 | t: ByNameImplicit[Encoder[S]] 15 | ): Application[SealedTraitSelector[P], SealedTag[S], TypeAlias.TypeHList2[Class[S], String]] = 16 | new Application[SealedTraitSelector[P], SealedTag[S], TypeAlias.TypeHList2[Class[S], String]] { 17 | override def application(context: Context[SealedTraitSelector[P]]): JsonEncoder[P, Class[S], String] = 18 | new JsonEncoder[P, Class[S], String] { 19 | override def p(model: P, classTags: Class[S], labelled: String): Option[(String, Json)] = { 20 | if (classTags.isInstance(model)) 21 | Some((labelled, t.value(classTags.cast(model)))) 22 | else 23 | Option.empty 24 | } 25 | } 26 | } 27 | } 28 | 29 | trait JsonEncoder[H, T, II] { 30 | def p(model: H, classTags: T, labelled: II): Option[(String, Json)] 31 | } 32 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2/zsg/testkit/circe/encoder/Utils.scala: -------------------------------------------------------------------------------- 1 | package io.circe 2 | 3 | import java.util 4 | 5 | object Utils { 6 | final def jsonObjectFromMap(link: util.LinkedHashMap[String, Json]): JsonObject = JsonObject.fromLinkedHashMap(link) 7 | } 8 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2/zsg/testkit/circe/encoder/ZsgJsonObjectContext.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.encoder 2 | 3 | import io.circe.Json 4 | import zsg.{Context, Plus, TypeHList} 5 | 6 | object ZsgJsonObjectContext extends Context[JsonObjectFunc] { 7 | override def append[X <: TypeHList, Y <: TypeHList, Z <: TypeHList]( 8 | x: JsonObjectAppender[X#Head, X#Tail#Head], 9 | y: JsonObjectAppender[Y#Head, Y#Tail#Head] 10 | )(plus: Plus[X, Y, Z]): JsonObjectAppender[Z#Head, Z#Tail#Head] = new JsonObjectAppender[Z#Head, Z#Tail#Head] { 11 | override def appendField(tt: Z#Tail#Head, m: List[(String, Json)]): List[(String, Json)] = { 12 | val m1 = y.appendField(plus.tail.takeTail(tt), m) 13 | x.appendField(plus.tail.takeHead(tt), m1) 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2/zsg/testkit/circe/encoder/ZsgSealedContext.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.encoder 2 | 3 | import io.circe.Json 4 | import zsg.{Context, Plus, TypeHList} 5 | 6 | class ZsgSealedContext[H] extends Context[SealedTraitSelector[H]] { 7 | override def append[X <: TypeHList, Y <: TypeHList, Z <: TypeHList](x: SealedTraitSelector[H]#H[X], y: SealedTraitSelector[H]#H[Y])( 8 | plus: Plus[X, Y, Z] 9 | ): SealedTraitSelector[H]#H[Z] = 10 | new JsonEncoder[H, Z#Head, Z#Tail#Head] { 11 | override def p(model: H, classTags: Z#Head, labelled: Z#Tail#Head): Option[(String, Json)] = { 12 | val a = x.p(model, plus.takeHead(classTags), plus.tail.takeHead(labelled)) 13 | a.orElse(y.p(model, plus.takeTail(classTags), plus.tail.takeTail(labelled))) 14 | } 15 | } 16 | } 17 | 18 | object ZsgSealedContext { 19 | def c[H]: ZsgSealedContext[H] = new ZsgSealedContext[H] 20 | } 21 | -------------------------------------------------------------------------------- /modules/testkit/src/main/scala-2/zsg/testkit/model/SimpleModel1.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.model 2 | 3 | import zsg.macros.single.deficient.{DeficientProperty, ModelProperty} 4 | 5 | import scala.annotation.meta.getter 6 | 7 | case class Test01[T](ii: T, i3: String, i4: Int) 8 | case class Test02(i3: String, i4: Int) 9 | case class Test03(i3: String, i4: Int, fg: Option[Test04]) 10 | case class Test04(i3: String, i4: Int, gf: List[Test03]) 11 | 12 | sealed trait Test05[T] 13 | case class Test06[T](i1: String, i2: Int) extends Test05[T] 14 | case class Test07[T](i1: T, i2: Int) extends Test05[T] 15 | case class Test08(i1: String, i2: Int) extends Test05[String] 16 | case object Test09 extends Test05[String] 17 | 18 | case class Test10[T](i1: String, name: String, i3: T, i4: Long, i5: Short) 19 | case class Test11[T](name: String, i3: T) 20 | 21 | trait Test12Trait { 22 | @(ModelProperty @getter) 23 | val test10: Test10[T] 24 | @DeficientProperty 25 | def test11: Test11[T] 26 | type T 27 | } 28 | trait Test13TraitImpl[T1] extends Test12Trait { 29 | override type T = T1 30 | } 31 | 32 | case class Test14(i1: String, i4: Long, i5: Short) 33 | -------------------------------------------------------------------------------- /modules/testkit/src/test/scala-2/zsg/testkit/circe/test1/CirceModel.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.test1 2 | 3 | object CirceModel { 4 | 5 | import io.circe.syntax._ 6 | import io.circe.generic.auto._ 7 | 8 | val i1Json = Instance.i1.asJson 9 | val i2Json = Instance.i2.asJson 10 | val i3Json = Instance.i3.asJson 11 | 12 | val i6Json = Instance.i6.asJson 13 | val i7Json = Instance.i7.asJson 14 | val i8Json = Instance.i8.asJson 15 | val i9Json = Instance.i9.asJson 16 | 17 | } 18 | -------------------------------------------------------------------------------- /modules/testkit/src/test/scala-2/zsg/testkit/circe/test1/Instance.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.test1 2 | 3 | import zsg.testkit.model._ 4 | import io.circe.Json 5 | 6 | object Instance { 7 | 8 | val i1 = Test01("name", "test01", 123) 9 | val i2 = Test02("test02", 123) 10 | val i3 = Test03("test06", 123, Option(Test04("test07", 789, List(Test03("test06", 456, Option.empty))))) 11 | val i4 = io.circe.parser.parse("""{"i3":"test07","i4":123,"gf":[]}""").right.getOrElse((throw new Exception()): Json) 12 | 13 | val i6: Test05[String] = Test06("test06", 2) 14 | val i7: Test05[String] = Test07("7", 2) 15 | val i8: Test05[String] = Test08("test08", 2) 16 | val i9: Test05[String] = Test09 17 | 18 | } 19 | -------------------------------------------------------------------------------- /modules/testkit/src/test/scala-2/zsg/testkit/circe/test1/ZsgCirceModel.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.test1 2 | 3 | import io.circe.Encoder 4 | import zsg.Application 5 | import zsg.testkit.model._ 6 | import zsg.testkit.circe.{ACirce, CirceVersionCompat} 7 | 8 | trait ZsgCirceImplicit1 { 9 | 10 | import ZsgCirceImplicit2._ 11 | 12 | implicit def test01_en_implicit[T](implicit i: Encoder[T]): CirceVersionCompat.JsonObjectEncoder[Test01[T]] = ACirce.encodeCaseClass 13 | implicit def test02_en_implicit: CirceVersionCompat.JsonObjectEncoder[Test02] = ACirce.encodeCaseClass 14 | implicit def test03_en_implicit: CirceVersionCompat.JsonObjectEncoder[Test03] = ACirce.encodeCaseClass 15 | 16 | implicit def test05_en_implicit: CirceVersionCompat.JsonObjectEncoder[Test05[String]] = ACirce.encodeSealed 17 | 18 | case class Test111(i3: String, i4: Long, i44: Int) 19 | 20 | } 21 | 22 | object ZsgCirceImplicit1 extends ZsgCirceImplicit1 23 | 24 | trait ZsgCirceImplicit2 { 25 | 26 | import ZsgCirceImplicit1._ 27 | 28 | implicit def test04_en_implicit: CirceVersionCompat.JsonObjectEncoder[Test04] = ACirce.encodeCaseClass 29 | 30 | implicit def test06_en_implicit: CirceVersionCompat.JsonObjectEncoder[Test06[String]] = ACirce.encodeCaseClass 31 | implicit def test07_en_implicit: CirceVersionCompat.JsonObjectEncoder[Test07[String]] = ACirce.encodeCaseClass 32 | implicit def test08_en_implicit: CirceVersionCompat.JsonObjectEncoder[Test08] = ACirce.encodeCaseClass 33 | implicit def test09_en_implicit: CirceVersionCompat.JsonObjectEncoder[Test09.type] = ACirce.encodeCaseObject 34 | 35 | } 36 | 37 | object ZsgCirceImplicit2 extends ZsgCirceImplicit2 38 | 39 | object ZsgCirceModel { 40 | 41 | import io.circe.syntax._ 42 | import ZsgCirceImplicit1._ 43 | import ZsgCirceImplicit2._ 44 | 45 | val i1Json = Instance.i1.asJson 46 | val i2Json = Instance.i2.asJson 47 | val i3Json = Instance.i3.asJson 48 | 49 | val i6Json = Instance.i6.asJson 50 | val i7Json = Instance.i7.asJson 51 | val i8Json = Instance.i8.asJson 52 | val i9Json = Instance.i9.asJson 53 | 54 | } 55 | -------------------------------------------------------------------------------- /modules/testkit/src/test/scala-2/zsg/testkit/circe/test1/ZsgWithCirceEncoderTest.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.test1 2 | 3 | import zio.Console._ 4 | import zio.test._ 5 | import zio.test.Assertion._ 6 | import zio.test.environment._ 7 | 8 | object ZsgWithCirceEncoderTest extends DefaultRunnableSpec { 9 | 10 | override def spec = suite("zsg encoder")( 11 | test("generic the same case class json object as circe") { 12 | val assert1 = assert(ZsgCirceModel.i1Json)(equalTo(CirceModel.i1Json)) 13 | val assert2 = assert(ZsgCirceModel.i2Json)(equalTo(CirceModel.i2Json)) 14 | val assert3 = assert(ZsgCirceModel.i3Json)(equalTo(CirceModel.i3Json)) 15 | 16 | val assert4 = assert(ZsgCirceModel.i1Json.noSpaces)(equalTo(CirceModel.i1Json.noSpaces)) 17 | val assert5 = assert(ZsgCirceModel.i2Json.noSpaces)(equalTo(CirceModel.i2Json.noSpaces)) 18 | val assert6 = assert(ZsgCirceModel.i3Json.noSpaces)(equalTo(CirceModel.i3Json.noSpaces)) 19 | assert1 && assert2 && assert3 && assert4 && assert5 && assert6 20 | }, 21 | test("generic the same sealed trait json object as circe") { 22 | val assert1 = assert(ZsgCirceModel.i6Json)(equalTo(CirceModel.i6Json)) 23 | val assert2 = assert(ZsgCirceModel.i7Json)(equalTo(CirceModel.i7Json)) 24 | val assert3 = assert(ZsgCirceModel.i8Json)(equalTo(CirceModel.i8Json)) 25 | val assert4 = assert(ZsgCirceModel.i9Json)(equalTo(CirceModel.i9Json)) 26 | 27 | val assert5 = assert(ZsgCirceModel.i6Json.noSpaces)(equalTo(CirceModel.i6Json.noSpaces)) 28 | val assert6 = assert(ZsgCirceModel.i7Json.noSpaces)(equalTo(CirceModel.i7Json.noSpaces)) 29 | val assert7 = assert(ZsgCirceModel.i8Json.noSpaces)(equalTo(CirceModel.i8Json.noSpaces)) 30 | val assert8 = assert(ZsgCirceModel.i9Json.noSpaces)(equalTo(CirceModel.i9Json.noSpaces)) 31 | assert1 && assert2 && assert3 && assert4 && assert5 && assert6 && assert7 && assert8 32 | } 33 | ) 34 | 35 | } 36 | -------------------------------------------------------------------------------- /modules/testkit/src/test/scala-2/zsg/testkit/circe/test2/CirceModel.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.test2 2 | 3 | import zsg.testkit.model.{Test01, Test02, Test03, Test05} 4 | 5 | object CirceModel { 6 | 7 | import io.circe.generic.auto._ 8 | 9 | val i1_1FromJson = Instance.i1.as[Test01[String]] 10 | val i1_2FromJson = Instance.i1.as[Test01[Int]] 11 | val i2FromJson = Instance.i2.as[Test02] 12 | val i3FromJson = Instance.i3.as[Test03] 13 | 14 | val i6FromJson = Instance.i6Json.as[Test05[String]] 15 | val i7FromJson = Instance.i7Json.as[Test05[String]] 16 | val i8FromJson = Instance.i8Json.as[Test05[String]] 17 | val i9FromJson = Instance.i9Json.as[Test05[String]] 18 | 19 | } 20 | -------------------------------------------------------------------------------- /modules/testkit/src/test/scala-2/zsg/testkit/circe/test2/Instance.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.test2 2 | 3 | import zsg.testkit.model._ 4 | 5 | object Instance { 6 | 7 | import io.circe.syntax._ 8 | import io.circe.generic.auto._ 9 | 10 | val i1 = Test01(2, "test01", 123).asJson 11 | val i2 = Test02("test02", 123).asJson 12 | val i3 = Test03("test06", 123, Option(Test04("test07", 789, List(Test03("test06", 456, Option.empty))))).asJson 13 | 14 | val i6: Test05[String] = Test06("test06", 2) 15 | val i7: Test05[String] = Test07("7", 2) 16 | val i8: Test05[String] = Test08("test08", 2) 17 | val i9: Test05[String] = Test09 18 | 19 | val i6Json = i6.asJson 20 | val i7Json = i7.asJson 21 | val i8Json = i8.asJson 22 | val i9Json = i9.asJson 23 | 24 | } 25 | -------------------------------------------------------------------------------- /modules/testkit/src/test/scala-2/zsg/testkit/circe/test2/ZsgCirceModel.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.test2 2 | 3 | import zsg.testkit.circe.ACirce 4 | import io.circe.Decoder 5 | import zsg.testkit.model._ 6 | 7 | trait ZsgCirceImplicit1 { 8 | 9 | import ZsgCirceImplicit2._ 10 | 11 | implicit def test02_de_implicit: Decoder[Test02] = ACirce.decodeCaseClass 12 | implicit def test04_de_implicit: Decoder[Test04] = ACirce.decodeCaseClass 13 | 14 | } 15 | 16 | object ZsgCirceImplicit1 extends ZsgCirceImplicit1 17 | 18 | trait ZsgCirceImplicit2 { 19 | 20 | import ZsgCirceImplicit1._ 21 | 22 | implicit def test01_de_implicit[T](implicit de: Decoder[T]): Decoder[Test01[T]] = ACirce.decodeCaseClass 23 | implicit def test03_de_implicit: Decoder[Test03] = ACirce.decodeCaseClass 24 | 25 | implicit def test05_de_implicit: Decoder[Test05[String]] = ACirce.decodeSealed 26 | implicit def test06_de_implicit: Decoder[Test06[String]] = ACirce.decodeCaseClass 27 | implicit def test07_de_implicit: Decoder[Test07[String]] = ACirce.decodeCaseClass 28 | implicit def test08_de_implicit: Decoder[Test08] = ACirce.decodeCaseClass 29 | implicit def test09_de_implicit: Decoder[Test09.type] = Decoder.instance(f => Right(Test09)) 30 | 31 | } 32 | 33 | object ZsgCirceImplicit2 extends ZsgCirceImplicit2 34 | 35 | object ZsgCirceModel { 36 | 37 | import ZsgCirceImplicit1._ 38 | import ZsgCirceImplicit2._ 39 | 40 | val i1_1FromJson = Instance.i1.as[Test01[String]] 41 | val i1_2FromJson = Instance.i1.as[Test01[Int]] 42 | val i2FromJson = Instance.i2.as[Test02] 43 | val i3FromJson = Instance.i3.as[Test03] 44 | 45 | val i6FromJson = Instance.i6Json.as[Test05[String]] 46 | val i7FromJson = Instance.i7Json.as[Test05[String]] 47 | val i8FromJson = Instance.i8Json.as[Test05[String]] 48 | val i9FromJson = Instance.i9Json.as[Test05[String]] 49 | 50 | } 51 | -------------------------------------------------------------------------------- /modules/testkit/src/test/scala-2/zsg/testkit/circe/test2/ZsgWithDecoderEncoderTest.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.test2 2 | 3 | import zsg.testkit.model._ 4 | 5 | import zio.Console._ 6 | import zio.test._ 7 | import zio.test.Assertion._ 8 | import zio.test.environment._ 9 | 10 | object ZsgWithDecoderEncoderTest extends DefaultRunnableSpec { 11 | 12 | override def spec = suite("zsg encoder")( 13 | test("generic the same json object as circe") { 14 | val assert1 = assert(ZsgCirceModel.i1_1FromJson)(equalTo(CirceModel.i1_1FromJson)) 15 | val assert2 = assert(ZsgCirceModel.i1_2FromJson)(equalTo(CirceModel.i1_2FromJson)) 16 | 17 | val assert3 = assert(ZsgCirceModel.i1_1FromJson.isRight)(equalTo(false)) 18 | val assert4 = assert(ZsgCirceModel.i1_2FromJson.isRight)(equalTo(true)) 19 | val assert5 = assert(CirceModel.i1_1FromJson.isRight)(equalTo(false)) 20 | val assert6 = assert(CirceModel.i1_2FromJson.isRight)(equalTo(true)) 21 | 22 | val assert7 = assert(ZsgCirceModel.i2FromJson)(equalTo(CirceModel.i2FromJson)) 23 | val assert8 = assert(ZsgCirceModel.i3FromJson)(equalTo(CirceModel.i3FromJson)) 24 | 25 | assert1 && assert2 && assert3 && assert4 && assert5 && assert6 && assert7 && assert8 26 | }, 27 | test("generic the same sealed trait json object as circe") { 28 | val assert1 = assert(ZsgCirceModel.i6FromJson.isRight)(equalTo(true)) 29 | val assert2 = assert(ZsgCirceModel.i7FromJson.isRight)(equalTo(true)) 30 | val assert3 = assert(ZsgCirceModel.i8FromJson.isRight)(equalTo(true)) 31 | val assert4 = assert(ZsgCirceModel.i9FromJson.isRight)(equalTo(true)) 32 | 33 | val assert5 = assert(CirceModel.i6FromJson.isRight)(equalTo(true)) 34 | val assert6 = assert(CirceModel.i7FromJson.isRight)(equalTo(true)) 35 | val assert7 = assert(CirceModel.i8FromJson.isRight)(equalTo(true)) 36 | val assert8 = assert(CirceModel.i9FromJson.isRight)(equalTo(true)) 37 | 38 | val assert9 = assert(ZsgCirceModel.i6FromJson)(equalTo(CirceModel.i6FromJson)) 39 | val assert10 = assert(ZsgCirceModel.i7FromJson)(equalTo(CirceModel.i7FromJson)) 40 | val assert11 = assert(ZsgCirceModel.i8FromJson)(equalTo(CirceModel.i8FromJson)) 41 | val assert12 = assert(ZsgCirceModel.i9FromJson)(equalTo(CirceModel.i9FromJson)) 42 | 43 | val assert13 = 44 | assert(ZsgCirceModel.i6FromJson.right.getOrElse((throw new Exception()): Test05[String]).isInstanceOf[Test06[_]])(equalTo(true)) 45 | val assert14 = 46 | assert(ZsgCirceModel.i7FromJson.right.getOrElse((throw new Exception()): Test05[String]).isInstanceOf[Test07[_]])(equalTo(true)) 47 | val assert15 = 48 | assert(ZsgCirceModel.i8FromJson.right.getOrElse((throw new Exception()): Test05[String]).isInstanceOf[Test08])(equalTo(true)) 49 | val assert16 = 50 | assert(ZsgCirceModel.i9FromJson.right.getOrElse((throw new Exception()): Test05[String]).isInstanceOf[Test09.type])(equalTo(true)) 51 | 52 | val assert17 = 53 | assert(ZsgCirceModel.i6FromJson.right.getOrElse((throw new Exception()): Test05[String]).isInstanceOf[Test05[_]])(equalTo(true)) 54 | val assert18 = 55 | assert(ZsgCirceModel.i7FromJson.right.getOrElse((throw new Exception()): Test05[String]).isInstanceOf[Test05[_]])(equalTo(true)) 56 | val assert19 = 57 | assert(ZsgCirceModel.i8FromJson.right.getOrElse((throw new Exception()): Test05[String]).isInstanceOf[Test05[_]])(equalTo(true)) 58 | val assert20 = 59 | assert(ZsgCirceModel.i9FromJson.right.getOrElse((throw new Exception()): Test05[String]).isInstanceOf[Test05[_]])(equalTo(true)) 60 | 61 | assert1 && assert2 && assert3 && assert4 && assert5 && assert6 && assert7 && assert8 && assert9 && assert10 && assert11 && assert12 && assert13 && assert14 && assert15 && assert16 && assert17 && assert18 && assert19 && assert20 62 | } 63 | ) 64 | 65 | } 66 | -------------------------------------------------------------------------------- /modules/testkit/src/test/scala-2/zsg/testkit/circe/test3/Asuna.scala.1111: -------------------------------------------------------------------------------- 1 | package asuna.testkit.circe.test3 2 | 3 | import asuna.macros.single.deficient.AsunaTupleApply 4 | import asuna.testkit.circe.ACirce 5 | import asuna.testkit.model._ 6 | import io.circe.Encoder 7 | import io.circe.syntax._ 8 | 9 | trait Poly1 { 10 | 11 | implicit val test12_en_implicit: Encoder[Test12Trait] = ACirce.encodeTuple 12 | implicit def test10_de_implicit[T]: Encoder[Test10[T]] = ACirce.mapTupleEncoder(AsunaTupleApply[Test10[T], Test13TraitImpl[T]], Encoder[Test12Trait]) 13 | implicit val test14_en_implicit: Encoder[Test14] = ACirce.encodeCaseClass 14 | 15 | } 16 | 17 | object Poly1 extends Poly1 18 | 19 | object Asuna { 20 | 21 | import Poly1._ 22 | 23 | val i10Json = Instance.i10.asJson 24 | val i14Json = Instance.i14.asJson 25 | 26 | } 27 | -------------------------------------------------------------------------------- /modules/testkit/src/test/scala-2/zsg/testkit/circe/test3/AsunaWithDecoderEncoderTest.scala.1111: -------------------------------------------------------------------------------- 1 | package asuna.testkit.circe.test3 2 | 3 | import org.scalatest.funspec.AnyFunSpec 4 | import org.scalatest.matchers.should.Matchers 5 | 6 | class AsunaWithDecoderEncoderTest extends AnyFunSpec with Matchers { 7 | 8 | describe("asuna encoder") { 9 | it("generic the same json object with tuple encoder") { 10 | Asuna.i10Json shouldBe Asuna.i14Json 11 | } 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /modules/testkit/src/test/scala-2/zsg/testkit/circe/test3/Instance.scala: -------------------------------------------------------------------------------- 1 | package zsg.testkit.circe.test3 2 | 3 | import java.util.Date 4 | 5 | import zsg.testkit.model._ 6 | 7 | object Instance { 8 | 9 | val i10 = Test10(i1 = "i1", name = "1234", i3 = new Date(), i4 = 22, i5 = 25) 10 | val i14 = Test14(i1 = "i1", i4 = 22, i5 = 25) 11 | 12 | } 13 | -------------------------------------------------------------------------------- /modules/testkit/version.sbt: -------------------------------------------------------------------------------- 1 | name := "zsg-testkit" 2 | CommonSettings.projectVersionSetting 3 | -------------------------------------------------------------------------------- /project/CommonSettings.scala: -------------------------------------------------------------------------------- 1 | import org.scalafmt.sbt.ScalafmtPlugin 2 | import org.scalafmt.sbt.ScalafmtPlugin.autoImport._ 3 | import sbt._ 4 | import sbt.Keys._ 5 | 6 | object CommonSettings { 7 | 8 | private val scalaOptionSettings = scalacOptions ++= Seq("-feature", "-deprecation", "-encoding", "utf-8") 9 | private val scalafmtSettings = ScalafmtPlugin.autoImport.scalafmtOnCompile := true 10 | private val scalafmtCheckSettings = scalafmtCheckAll := { 11 | (Compile / scalafmtSbtCheck).value 12 | (Compile / scalafmtCheck).value 13 | (Test / scalafmtCheck).value 14 | } 15 | private val scalafmtSettings2 = scalafmtAll := { 16 | (Compile / scalafmtSbt).value 17 | (Compile / scalafmt).value 18 | (Test / scalafmt).value 19 | } 20 | private val packageSettings = Seq(transitiveClassifiers := Seq("sources"), packageDoc / publishArtifact := false) 21 | private val testSettings = testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") 22 | 23 | def addDirectory(sourceFile: File, c: String, parVersion: Option[(Long, Long)]): Seq[File] = parVersion match { 24 | case Some((2, 11)) => 25 | Seq(sourceFile / c / "scala-2", sourceFile / c / "scala-2.11", sourceFile / c / "scala-2.11-2.12") 26 | case Some((2, 12)) => 27 | Seq(sourceFile / c / "scala-2", sourceFile / c / "scala-2.11-2.12", sourceFile / c / "scala-2.12", sourceFile / c / "scala-2.12-2.13") 28 | case Some((2, 13)) => 29 | Seq(sourceFile / c / "scala-2", sourceFile / c / "scala-2.12-2.13", sourceFile / c / "scala-2.13") 30 | case Some((2, _)) => Seq(sourceFile / c / "scala-2") 31 | case Some((3, _)) => Seq(sourceFile / c / "scala-3") 32 | case _ => Seq.empty 33 | } 34 | 35 | private val mainDirSetting = Compile / unmanagedSourceDirectories ++= { 36 | addDirectory(sourceDirectory.value, "main", CrossVersion.partialVersion(scalaVersion.value)) ++: addDirectory( 37 | sourceDirectory.value, 38 | "codegen", 39 | CrossVersion.partialVersion(scalaVersion.value) 40 | ) 41 | } 42 | private val testDirSetting = Test / unmanagedSourceDirectories ++= { 43 | addDirectory(sourceDirectory.value, "test", CrossVersion.partialVersion(scalaVersion.value)) 44 | } 45 | 46 | val settings = 47 | scalafmtSettings +: 48 | scalafmtCheckSettings +: 49 | scalafmtSettings2 +: 50 | mainDirSetting +: 51 | testDirSetting +: 52 | scalaOptionSettings +: 53 | testSettings +: 54 | packageSettings 55 | 56 | object project { 57 | val version = "0.0.5-SNAP2021091203" 58 | val organization = "org.scalax.zsg" 59 | val license = "MIT" 60 | val licenseUrl = "http://opensource.org/licenses/MIT" 61 | } 62 | 63 | private val versionSetting = version := project.version 64 | private val organizationSetting = organization := project.organization 65 | private val licensesSetting = licenses += (project.license, url(project.licenseUrl)) 66 | 67 | val projectVersionSetting = Seq(versionSetting, organizationSetting, licensesSetting) 68 | 69 | } 70 | -------------------------------------------------------------------------------- /project/Dependencies.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import sbt.Keys._ 3 | 4 | object Dependencies { 5 | 6 | object versions { 7 | val circe_2_11 = "0.11.2" 8 | val circe_2_13 = "0.15.0-M1" 9 | val zio = "2.0.0-M3" 10 | val slick = "2.0.0-M3" 11 | val slf4j = "1.7.32" 12 | val collectionCompat = "2.6.0" 13 | val commonsCodec = "1.14" 14 | val commonsIO = "2.6" 15 | } 16 | 17 | def circeDependencies(scalaVersion: String): Seq[ModuleID] = CrossVersion.partialVersion(scalaVersion) match { 18 | case Some((2, 11)) => 19 | List( 20 | "io.circe" %% "circe-derivation" % "0.11.0-M3", 21 | "io.circe" %% "circe-core" % versions.circe_2_11, 22 | "io.circe" %% "circe-generic" % versions.circe_2_11, 23 | "io.circe" %% "circe-parser" % versions.circe_2_11 24 | ) 25 | case Some((2, x)) if x >= 12 => 26 | List( 27 | "io.circe" %% "circe-derivation" % "0.13.0-M5", 28 | "io.circe" %% "circe-core" % versions.circe_2_13, 29 | "io.circe" %% "circe-generic" % versions.circe_2_13, 30 | "io.circe" %% "circe-parser" % versions.circe_2_13 31 | ) 32 | case _ => 33 | List( 34 | "io.circe" %% "circe-core" % versions.circe_2_13, 35 | "io.circe" %% "circe-generic" % versions.circe_2_13, 36 | "io.circe" %% "circe-parser" % versions.circe_2_13 37 | ) 38 | } 39 | 40 | val zioTest = List( 41 | "dev.zio" %% "zio-test" % versions.zio % "test", 42 | "dev.zio" %% "zio-test-sbt" % versions.zio % "test" 43 | ) 44 | 45 | val slick = List( 46 | "com.typesafe.slick" %% "slick" % versions.slick, 47 | "com.typesafe.slick" %% "slick-codegen" % versions.slick 48 | ) 49 | 50 | val upickleDependencies = List("com.lihaoyi" %% "upickle" % "1.4.1") 51 | 52 | def scalaReflect(scalaVersion: String) = CrossVersion.partialVersion(scalaVersion) match { 53 | case Some((2, _)) => List("org.scala-lang" % "scala-reflect" % scalaVersion) 54 | case _ => List.empty 55 | } 56 | 57 | val slf4j = "org.slf4j" % "slf4j-simple" % versions.slf4j 58 | 59 | val scalaCollectionCompat = "org.scala-lang.modules" %% "scala-collection-compat" % versions.collectionCompat 60 | 61 | val commonsCodec = "commons-codec" % "commons-codec" % versions.commonsCodec 62 | 63 | val commonsIo = "commons-io" % "commons-io" % versions.commonsIO 64 | 65 | } 66 | -------------------------------------------------------------------------------- /project/ZsgSettings.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import sbt.Keys._ 3 | import sbtghactions.GenerativeKeys._ 4 | import sbtghactions._ 5 | 6 | object ZsgSettings { 7 | 8 | object versions { 9 | val currentScala = "2.13.10" 10 | val scala212 = "2.12.14" 11 | val scala211 = "2.11.12" 12 | val dotty = "3.1.1" 13 | } 14 | 15 | private val commonScalaVersionSetting = scalaVersion := versions.currentScala 16 | private val setting2 = crossScalaVersions := Seq(versions.scala211, versions.scala212, versions.currentScala) 17 | private val setting3 = scalaVersion := versions.currentScala 18 | private val setting6 = crossScalaVersions := Seq(versions.dotty, versions.scala212, versions.scala211, versions.currentScala) 19 | private val setting8 = crossScalaVersions := Seq(versions.scala212, versions.currentScala) 20 | 21 | private val githubWorkflowSettings = Seq( 22 | ThisBuild / githubWorkflowJavaVersions := Seq(JavaSpec(JavaSpec.Distribution.Adopt, "8.0")), 23 | ThisBuild / githubWorkflowScalaVersions := Seq(versions.scala212, versions.currentScala, versions.dotty), 24 | ThisBuild / githubWorkflowPublishTargetBranches := Nil, 25 | ThisBuild / githubWorkflowBuild := Seq( 26 | WorkflowStep.Sbt(List("clean", "coverage", "test"), id = None, name = Some("Test")), 27 | WorkflowStep.Sbt(List("coverageReport"), id = None, name = Some("Coverage")), 28 | WorkflowStep.Use(UseRef.Public("codecov", "codecov-action", "v1")) 29 | ) 30 | ) 31 | 32 | object settings { 33 | val scalaVersion = Seq(commonScalaVersionSetting, setting2) 34 | val scala_2_12_And_2_13 = Seq(setting3, setting8) 35 | val dottyVersion = Seq(commonScalaVersionSetting, setting6) 36 | val githubWorkflow = githubWorkflowSettings 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.7.1 -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addDependencyTreePlugin 2 | addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") 3 | addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.0-M4") 4 | addSbtPlugin("com.github.sbt" % "sbt-release" % "1.1.0") 5 | addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.5.1") 6 | addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.3") 7 | addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.14.2") 8 | -------------------------------------------------------------------------------- /version.sbt: -------------------------------------------------------------------------------- 1 | CommonSettings.projectVersionSetting 2 | name := "zsg" 3 | --------------------------------------------------------------------------------