Repository: 1Password/typeshare (rust)
Issue: Kotlin struct properties should be immutable
Currently in other languages (where it exists) typeshare emits properties that are immutable. In Kotlin, these are emitted as `var` which is mutable. To stay consistent, we should emit as `val`.

For example, this Rust type:
```rs
pub struct Foo {
    pub a: i8,
    pub b: i16,
    pub c: i32,
    pub e: u8,
    pub f: u16,
    pub g: u32,
}
```

produces this Swift type:

```swift
public struct Foo: Codable {
  public let a: Int8
  public let b: Int16
  public let c: Int32
  public let e: UInt8
  public let f: UInt16
  public let g: UInt32

  public init(a: Int8, b: Int16, c: Int32, e: UInt8, f: UInt16, g: UInt32) {
    self.a = a
    self.b = b
    self.c = c
    self.e = e
    self.f = f
    self.g = g
  }
}
```

and this Kotlin type:

```kt
data class Foo (
  var a: Byte,
  var b: Short,
  var c: Int,
  var e: UByte,
  var f: UShort,
  var g: UInt
)
```
Pull request description: Change Kotlin to use val
Resolves #38 

Literally a single character change to keep Kotlin consistent

Patch:
diff --git a/core/src/language/kotlin.rs b/core/src/language/kotlin.rs
index f40e507..cb399a5 100644
--- a/core/src/language/kotlin.rs
+++ b/core/src/language/kotlin.rs
@@ -309,7 +309,7 @@ impl Kotlin {
             .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
         write!(
             w,
-            "\tvar {}: {}{}",
+            "\tval {}: {}{}",
             remove_dash_from_identifier(&f.id.renamed),
             ty,
             (f.has_default && !f.ty.is_optional())


Test patch:
diff --git a/core/data/tests/anonymous_struct_with_rename/output.kt b/core/data/tests/anonymous_struct_with_rename/output.kt
index 3a925b8..29c9fa1 100644
--- a/core/data/tests/anonymous_struct_with_rename/output.kt
+++ b/core/data/tests/anonymous_struct_with_rename/output.kt
@@ -12,26 +12,26 @@ import kotlinx.serialization.*
 /// Generated type representing the anonymous struct variant `List` of the `AnonymousStructWithRename` Rust enum
 @Serializable
 data class AnonymousStructWithRenameListInner (
-	var list: List<String>
+	val list: List<String>
 )
 
 /// Generated type representing the anonymous struct variant `LongFieldNames` of the `AnonymousStructWithRename` Rust enum
 @Serializable
 data class AnonymousStructWithRenameLongFieldNamesInner (
-	var some_long_field_name: String,
-	var and: Boolean,
-	var but_one_more: List<String>
+	val some_long_field_name: String,
+	val and: Boolean,
+	val but_one_more: List<String>
 )
 
 /// Generated type representing the anonymous struct variant `KebabCase` of the `AnonymousStructWithRename` Rust enum
 @Serializable
 data class AnonymousStructWithRenameKebabCaseInner (
 	@SerialName("another-list")
-	var another_list: List<String>,
+	val another_list: List<String>,
 	@SerialName("camelCaseStringField")
-	var camelCaseStringField: String,
+	val camelCaseStringField: String,
 	@SerialName("something-else")
-	var something_else: Boolean
+	val something_else: Boolean
 )
 
 @Serializable
diff --git a/core/data/tests/can_apply_prefix_correctly/output.kt b/core/data/tests/can_apply_prefix_correctly/output.kt
index 9767240..641639d 100644
--- a/core/data/tests/can_apply_prefix_correctly/output.kt
+++ b/core/data/tests/can_apply_prefix_correctly/output.kt
@@ -11,7 +11,7 @@ import kotlinx.serialization.*
 
 @Serializable
 data class ItemDetailsFieldValue (
-	var hello: String
+	val hello: String
 )
 
 @Serializable
diff --git a/core/data/tests/can_generate_generic_enum/output.kt b/core/data/tests/can_generate_generic_enum/output.kt
index c5f8013..2baaaa0 100644
--- a/core/data/tests/can_generate_generic_enum/output.kt
+++ b/core/data/tests/can_generate_generic_enum/output.kt
@@ -11,7 +11,7 @@ import kotlinx.serialization.*
 
 @Serializable
 data class StructUsingGenericEnum (
-	var enum_field: GenericEnum<String, Short>
+	val enum_field: GenericEnum<String, Short>
 )
 
 @Serializable
@@ -40,27 +40,27 @@ sealed class GenericEnumUsingGenericEnum<T> {
 /// Generated type representing the anonymous struct variant `VariantF` of the `GenericEnumsUsingStructVariants` Rust enum
 @Serializable
 data class GenericEnumsUsingStructVariantsVariantFInner<T> (
-	var action: T
+	val action: T
 )
 
 /// Generated type representing the anonymous struct variant `VariantG` of the `GenericEnumsUsingStructVariants` Rust enum
 @Serializable
 data class GenericEnumsUsingStructVariantsVariantGInner<T, U> (
-	var action: T,
-	var response: U
+	val action: T,
+	val response: U
 )
 
 /// Generated type representing the anonymous struct variant `VariantH` of the `GenericEnumsUsingStructVariants` Rust enum
 @Serializable
 data class GenericEnumsUsingStructVariantsVariantHInner (
-	var non_generic: Int
+	val non_generic: Int
 )
 
 /// Generated type representing the anonymous struct variant `VariantI` of the `GenericEnumsUsingStructVariants` Rust enum
 @Serializable
 data class GenericEnumsUsingStructVariantsVariantIInner<T, U> (
-	var vec: List<T>,
-	var action: MyType<T, U>
+	val vec: List<T>,
+	val action: MyType<T, U>
 )
 
 @Serializable
diff --git a/core/data/tests/can_generate_generic_struct/output.kt b/core/data/tests/can_generate_generic_struct/output.kt
index 7f6eb86..274bb1f 100644
--- a/core/data/tests/can_generate_generic_struct/output.kt
+++ b/core/data/tests/can_generate_generic_struct/output.kt
@@ -11,15 +11,15 @@ import kotlinx.serialization.*
 
 @Serializable
 data class GenericStruct<A, B> (
-	var field_a: A,
-	var field_b: List<B>
+	val field_a: A,
+	val field_b: List<B>
 )
 
 @Serializable
 data class GenericStructUsingGenericStruct<T> (
-	var struct_field: GenericStruct<String, T>,
-	var second_struct_field: GenericStruct<T, String>,
-	var third_struct_field: GenericStruct<T, List<T>>
+	val struct_field: GenericStruct<String, T>,
+	val second_struct_field: GenericStruct<T, String>,
+	val third_struct_field: GenericStruct<T, List<T>>
 )
 
 @Serializable
diff --git a/core/data/tests/can_generate_simple_struct_with_a_comment/output.kt b/core/data/tests/can_generate_simple_struct_with_a_comment/output.kt
index c6ff80e..78166b6 100644
--- a/core/data/tests/can_generate_simple_struct_with_a_comment/output.kt
+++ b/core/data/tests/can_generate_simple_struct_with_a_comment/output.kt
@@ -16,10 +16,10 @@ class Location
 @Serializable
 data class Person (
 	/// This is another comment
-	var name: String,
-	var age: UByte,
-	var info: String? = null,
-	var emails: List<String>,
-	var location: Location
+	val name: String,
+	val age: UByte,
+	val info: String? = null,
+	val emails: List<String>,
+	val location: Location
 )
 
diff --git a/core/data/tests/can_generate_struct_with_skipped_fields/output.kt b/core/data/tests/can_generate_struct_with_skipped_fields/output.kt
index b511112..2bfa5c6 100644
--- a/core/data/tests/can_generate_struct_with_skipped_fields/output.kt
+++ b/core/data/tests/can_generate_struct_with_skipped_fields/output.kt
@@ -11,7 +11,7 @@ import kotlinx.serialization.*
 
 @Serializable
 data class MyStruct (
-	var a: Int,
-	var c: Int
+	val a: Int,
+	val c: Int
 )
 
diff --git a/core/data/tests/can_handle_anonymous_struct/output.kt b/core/data/tests/can_handle_anonymous_struct/output.kt
index a1ff938..f28ad83 100644
--- a/core/data/tests/can_handle_anonymous_struct/output.kt
+++ b/core/data/tests/can_handle_anonymous_struct/output.kt
@@ -13,16 +13,16 @@ import kotlinx.serialization.*
 @Serializable
 data class AutofilledByUsInner (
 	/// The UUID for the fill
-	var uuid: String
+	val uuid: String
 )
 
 /// Generated type representing the anonymous struct variant `SomethingElse` of the `AutofilledBy` Rust enum
 @Serializable
 data class AutofilledBySomethingElseInner (
 	/// The UUID for the fill
-	var uuid: String,
+	val uuid: String,
 	/// Some other thing
-	var thing: Int
+	val thing: Int
 )
 
 /// Enum keeping track of who autofilled a field
@@ -41,14 +41,14 @@ sealed class AutofilledBy {
 /// Generated type representing the anonymous struct variant `AnonVariant` of the `EnumWithManyVariants` Rust enum
 @Serializable
 data class EnumWithManyVariantsAnonVariantInner (
-	var uuid: String
+	val uuid: String
 )
 
 /// Generated type representing the anonymous struct variant `AnotherAnonVariant` of the `EnumWithManyVariants` Rust enum
 @Serializable
 data class EnumWithManyVariantsAnotherAnonVariantInner (
-	var uuid: String,
-	var thing: Int
+	val uuid: String,
+	val thing: Int
 )
 
 /// This is a comment (yareek sameek wuz here)
diff --git a/core/data/tests/can_handle_serde_rename/output.kt b/core/data/tests/can_handle_serde_rename/output.kt
index 0c61505..bce25b0 100644
--- a/core/data/tests/can_handle_serde_rename/output.kt
+++ b/core/data/tests/can_handle_serde_rename/output.kt
@@ -15,11 +15,11 @@ class OtherType
 /// This is a comment.
 @Serializable
 data class Person (
-	var name: String,
-	var age: UByte,
-	var extraSpecialFieldOne: Int,
-	var extraSpecialFieldTwo: List<String>? = null,
-	var nonStandardDataType: OtherType,
-	var nonStandardDataTypeInArray: List<OtherType>? = null
+	val name: String,
+	val age: UByte,
+	val extraSpecialFieldOne: Int,
+	val extraSpecialFieldTwo: List<String>? = null,
+	val nonStandardDataType: OtherType,
+	val nonStandardDataTypeInArray: List<OtherType>? = null
 )
 
diff --git a/core/data/tests/can_handle_serde_rename_all/output.kt b/core/data/tests/can_handle_serde_rename_all/output.kt
index 0237bd3..9b71133 100644
--- a/core/data/tests/can_handle_serde_rename_all/output.kt
+++ b/core/data/tests/can_handle_serde_rename_all/output.kt
@@ -12,18 +12,18 @@ import kotlinx.serialization.*
 /// This is a Person struct with camelCase rename
 @Serializable
 data class Person (
-	var firstName: String,
-	var lastName: String,
-	var age: UByte,
-	var extraSpecialField1: Int,
-	var extraSpecialField2: List<String>? = null
+	val firstName: String,
+	val lastName: String,
+	val age: UByte,
+	val extraSpecialField1: Int,
+	val extraSpecialField2: List<String>? = null
 )
 
 /// This is a Person2 struct with UPPERCASE rename
 @Serializable
 data class Person2 (
-	var FIRST_NAME: String,
-	var LAST_NAME: String,
-	var AGE: UByte
+	val FIRST_NAME: String,
+	val LAST_NAME: String,
+	val AGE: UByte
 )
 
diff --git a/core/data/tests/can_handle_serde_rename_on_top_level/output.kt b/core/data/tests/can_handle_serde_rename_on_top_level/output.kt
index 8a4dd14..3703ca8 100644
--- a/core/data/tests/can_handle_serde_rename_on_top_level/output.kt
+++ b/core/data/tests/can_handle_serde_rename_on_top_level/output.kt
@@ -15,11 +15,11 @@ class OtherType
 /// This is a comment.
 @Serializable
 data class PersonTwo (
-	var name: String,
-	var age: UByte,
-	var extraSpecialFieldOne: Int,
-	var extraSpecialFieldTwo: List<String>? = null,
-	var nonStandardDataType: OtherType,
-	var nonStandardDataTypeInArray: List<OtherType>? = null
+	val name: String,
+	val age: UByte,
+	val extraSpecialFieldOne: Int,
+	val extraSpecialFieldTwo: List<String>? = null,
+	val nonStandardDataType: OtherType,
+	val nonStandardDataTypeInArray: List<OtherType>? = null
 )
 
diff --git a/core/data/tests/can_handle_unit_type/output.kt b/core/data/tests/can_handle_unit_type/output.kt
index 144811e..355a4c1 100644
--- a/core/data/tests/can_handle_unit_type/output.kt
+++ b/core/data/tests/can_handle_unit_type/output.kt
@@ -12,7 +12,7 @@ import kotlinx.serialization.*
 /// This struct has a unit field
 @Serializable
 data class StructHasVoidType (
-	var thisIsAUnit: Unit
+	val thisIsAUnit: Unit
 )
 
 /// This enum has a variant associated with unit data
diff --git a/core/data/tests/generate_types/output.kt b/core/data/tests/generate_types/output.kt
index ff6e225..543fcbb 100644
--- a/core/data/tests/generate_types/output.kt
+++ b/core/data/tests/generate_types/output.kt
@@ -14,14 +14,14 @@ class CustomType
 
 @Serializable
 data class Types (
-	var s: String,
-	var static_s: String,
-	var int8: Byte,
-	var float: Float,
-	var double: Double,
-	var array: List<String>,
-	var dictionary: HashMap<String, Int>,
-	var optional_dictionary: HashMap<String, Int>? = null,
-	var custom_type: CustomType
+	val s: String,
+	val static_s: String,
+	val int8: Byte,
+	val float: Float,
+	val double: Double,
+	val array: List<String>,
+	val dictionary: HashMap<String, Int>,
+	val optional_dictionary: HashMap<String, Int>? = null,
+	val custom_type: CustomType
 )
 
diff --git a/core/data/tests/kebab_case_rename/output.kt b/core/data/tests/kebab_case_rename/output.kt
index 138f21b..bf34afb 100644
--- a/core/data/tests/kebab_case_rename/output.kt
+++ b/core/data/tests/kebab_case_rename/output.kt
@@ -13,10 +13,10 @@ import kotlinx.serialization.*
 @Serializable
 data class Things (
 	@SerialName("bla")
-	var bla: String,
+	val bla: String,
 	@SerialName("label")
-	var label: String? = null,
+	val label: String? = null,
 	@SerialName("label-left")
-	var label_left: String? = null
+	val label_left: String? = null
 )
 
diff --git a/core/data/tests/recursive_enum_decorator/output.kt b/core/data/tests/recursive_enum_decorator/output.kt
index a2888dd..47f9f70 100644
--- a/core/data/tests/recursive_enum_decorator/output.kt
+++ b/core/data/tests/recursive_enum_decorator/output.kt
@@ -25,13 +25,13 @@ sealed class Options {
 /// Generated type representing the anonymous struct variant `Exactly` of the `MoreOptions` Rust enum
 @Serializable
 data class MoreOptionsExactlyInner (
-	var config: String
+	val config: String
 )
 
 /// Generated type representing the anonymous struct variant `Built` of the `MoreOptions` Rust enum
 @Serializable
 data class MoreOptionsBuiltInner (
-	var top: MoreOptions
+	val top: MoreOptions
 )
 
 @Serializable
diff --git a/core/data/tests/resolves_qualified_type/output.kt b/core/data/tests/resolves_qualified_type/output.kt
index bebe4e4..b4d033e 100644
--- a/core/data/tests/resolves_qualified_type/output.kt
+++ b/core/data/tests/resolves_qualified_type/output.kt
@@ -11,11 +11,11 @@ import kotlinx.serialization.*
 
 @Serializable
 data class QualifiedTypes (
-	var unqualified: String,
-	var qualified: String,
-	var qualified_vec: List<String>,
-	var qualified_hashmap: HashMap<String, String>,
-	var qualified_optional: String? = null,
-	var qualfied_optional_hashmap_vec: HashMap<String, List<String>>? = null
+	val unqualified: String,
+	val qualified: String,
+	val qualified_vec: List<String>,
+	val qualified_hashmap: HashMap<String, String>,
+	val qualified_optional: String? = null,
+	val qualfied_optional_hashmap_vec: HashMap<String, List<String>>? = null
 )
 
diff --git a/core/data/tests/serialize_field_as/output.kt b/core/data/tests/serialize_field_as/output.kt
index 1a534be..d355918 100644
--- a/core/data/tests/serialize_field_as/output.kt
+++ b/core/data/tests/serialize_field_as/output.kt
@@ -11,8 +11,8 @@ import kotlinx.serialization.*
 
 @Serializable
 data class EditItemViewModelSaveRequest (
-	var context: String,
-	var values: List<EditItemSaveValue>,
-	var fill_action: AutoFillItemActionRequest? = null
+	val context: String,
+	val values: List<EditItemSaveValue>,
+	val fill_action: AutoFillItemActionRequest? = null
 )
 
diff --git a/core/data/tests/test_i54_u53_type/output.kt b/core/data/tests/test_i54_u53_type/output.kt
index d3a1b65..a22a133 100644
--- a/core/data/tests/test_i54_u53_type/output.kt
+++ b/core/data/tests/test_i54_u53_type/output.kt
@@ -11,7 +11,7 @@ import kotlinx.serialization.*
 
 @Serializable
 data class Foo (
-	var a: Long,
-	var b: ULong
+	val a: Long,
+	val b: ULong
 )
 
diff --git a/core/data/tests/test_serde_default_struct/output.kt b/core/data/tests/test_serde_default_struct/output.kt
index 41eb081..af8aa1a 100644
--- a/core/data/tests/test_serde_default_struct/output.kt
+++ b/core/data/tests/test_serde_default_struct/output.kt
@@ -11,6 +11,6 @@ import kotlinx.serialization.*
 
 @Serializable
 data class Foo (
-	var bar: Boolean? = null
+	val bar: Boolean? = null
 )
 
diff --git a/core/data/tests/test_serde_iso8601/output.kt b/core/data/tests/test_serde_iso8601/output.kt
index 4566fa8..f69b0b5 100644
--- a/core/data/tests/test_serde_iso8601/output.kt
+++ b/core/data/tests/test_serde_iso8601/output.kt
@@ -11,6 +11,6 @@ import kotlinx.serialization.*
 
 @Serializable
 data class Foo (
-	var time: String
+	val time: String
 )
 
diff --git a/core/data/tests/test_serde_url/output.kt b/core/data/tests/test_serde_url/output.kt
index 32434a8..6fd543c 100644
--- a/core/data/tests/test_serde_url/output.kt
+++ b/core/data/tests/test_serde_url/output.kt
@@ -11,6 +11,6 @@ import kotlinx.serialization.*
 
 @Serializable
 data class Foo (
-	var url: String
+	val url: String
 )
 
diff --git a/core/data/tests/test_type_alias/output.kt b/core/data/tests/test_type_alias/output.kt
index da9c568..5b765dc 100644
--- a/core/data/tests/test_type_alias/output.kt
+++ b/core/data/tests/test_type_alias/output.kt
@@ -13,6 +13,6 @@ typealias Bar = String
 
 @Serializable
 data class Foo (
-	var bar: Bar
+	val bar: Bar
 )
 
diff --git a/core/data/tests/use_correct_integer_types/output.kt b/core/data/tests/use_correct_integer_types/output.kt
index 991bc57..38f225b 100644
--- a/core/data/tests/use_correct_integer_types/output.kt
+++ b/core/data/tests/use_correct_integer_types/output.kt
@@ -12,11 +12,11 @@ import kotlinx.serialization.*
 /// This is a comment.
 @Serializable
 data class Foo (
-	var a: Byte,
-	var b: Short,
-	var c: Int,
-	var e: UByte,
-	var f: UShort,
-	var g: UInt
+	val a: Byte,
+	val b: Short,
+	val c: Int,
+	val e: UByte,
+	val f: UShort,
+	val g: UInt
 )