1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package androidx.navigation.safe.args.generator
18
19import androidx.navigation.safe.args.generator.ext.S
20import androidx.navigation.safe.args.generator.models.ResReference
21import androidx.navigation.safe.args.generator.models.accessor
22import com.squareup.javapoet.ClassName
23import com.squareup.javapoet.CodeBlock
24import com.squareup.javapoet.TypeName
25
26enum class NavType {
27
28    INT {
29        override fun typeName(): TypeName = TypeName.INT
30        override fun bundlePutMethod() = "putInt"
31        override fun bundleGetMethod() = "getInt"
32        override fun toString() = "integer"
33    },
34
35    FLOAT {
36        override fun typeName(): TypeName = TypeName.FLOAT
37        override fun bundlePutMethod() = "putFloat"
38        override fun bundleGetMethod() = "getFloat"
39        override fun toString() = "float"
40    },
41
42    STRING {
43        override fun typeName(): TypeName = ClassName.get(String::class.java)
44        override fun bundlePutMethod() = "putString"
45        override fun bundleGetMethod() = "getString"
46        override fun toString() = "string"
47    },
48
49    BOOLEAN {
50        override fun typeName(): TypeName = TypeName.BOOLEAN
51        override fun bundlePutMethod() = "putBoolean"
52        override fun bundleGetMethod() = "getBoolean"
53        override fun toString() = "boolean"
54    },
55
56    REFERENCE {
57        // it is internally the same as INT, but we don't want to allow to
58        // assignment between int and reference args
59        override fun typeName(): TypeName = TypeName.INT
60
61        override fun bundlePutMethod() = "putInt"
62        override fun bundleGetMethod() = "getInt"
63        override fun toString() = "reference"
64    };
65
66    abstract fun typeName(): TypeName
67    abstract fun bundlePutMethod(): String
68    abstract fun bundleGetMethod(): String
69
70    companion object {
71        fun from(name: String?) = when (name) {
72            "integer" -> NavType.INT
73            "float" -> NavType.FLOAT
74            "boolean" -> NavType.BOOLEAN
75            "reference" -> NavType.REFERENCE
76            "string" -> NavType.STRING
77            null -> NavType.STRING
78            else -> null
79        }
80    }
81}
82
83sealed class WriteableValue {
84    abstract fun write(): CodeBlock
85}
86
87data class ReferenceValue(private val resReference: ResReference) : WriteableValue() {
88    override fun write(): CodeBlock = CodeBlock.of(resReference.accessor())
89}
90
91data class StringValue(private val value: String) : WriteableValue() {
92    override fun write(): CodeBlock = CodeBlock.of(S, value)
93}
94
95// keeping value as String, it will help to preserve client format of it: hex, dec
96data class IntValue(private val value: String) : WriteableValue() {
97    override fun write(): CodeBlock = CodeBlock.of(value)
98}
99
100// keeping value as String, it will help to preserve client format of it: scientific, dot
101data class FloatValue(private val value: String) : WriteableValue() {
102    override fun write(): CodeBlock = CodeBlock.of("${value}F")
103}
104
105data class BooleanValue(private val value: String) : WriteableValue() {
106    override fun write(): CodeBlock = CodeBlock.of(value)
107}