Skip to content

Commit

Permalink
Support Rust slice type
Browse files Browse the repository at this point in the history
  • Loading branch information
czocher committed Jun 21, 2023
1 parent 913c5c2 commit 0b8bb7b
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 3 deletions.
5 changes: 5 additions & 0 deletions core/data/tests/can_generate_slice_of_user_type/input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[typeshare]
#[derive(Serialize)]
pub struct Video<'a> {
pub tags: &'a [Tag],
}
7 changes: 7 additions & 0 deletions core/data/tests/can_generate_slice_of_user_type/output.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package proto

import "encoding/json"

type Video struct {
Tags []Tag `json:"tags"`
}
12 changes: 12 additions & 0 deletions core/data/tests/can_generate_slice_of_user_type/output.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@file:NoLiveLiterals

package com.agilebits.onepassword

import androidx.compose.runtime.NoLiveLiterals
import kotlinx.serialization.*

@Serializable
data class Video (
val tags: List<Tag>
)

9 changes: 9 additions & 0 deletions core/data/tests/can_generate_slice_of_user_type/output.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.agilebits

package onepassword {

case class Video (
tags: Vector[Tag]
)

}
9 changes: 9 additions & 0 deletions core/data/tests/can_generate_slice_of_user_type/output.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation

public struct Video: Codable {
public let tags: [Tag]

public init(tags: [Tag]) {
self.tags = tags
}
}
4 changes: 4 additions & 0 deletions core/data/tests/can_generate_slice_of_user_type/output.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface Video {
tags: Tag[];
}

3 changes: 3 additions & 0 deletions core/src/language/go.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ impl Language for Go {
SpecialRustType::Array(rtype, len) => {
format!("[{}]{}", len, self.format_type(rtype, generic_types)?)
}
SpecialRustType::Slice(rtype) => {
format!("[]{}", self.format_type(rtype, generic_types)?)
}
SpecialRustType::Option(rtype) => {
format!("*{}", self.format_type(rtype, generic_types)?)
}
Expand Down
3 changes: 3 additions & 0 deletions core/src/language/kotlin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ impl Language for Kotlin {
SpecialRustType::Array(rtype, _) => {
format!("List<{}>", self.format_type(rtype, generic_types)?)
}
SpecialRustType::Slice(rtype) => {
format!("List<{}>", self.format_type(rtype, generic_types)?)
}
SpecialRustType::Option(rtype) => {
format!("{}?", self.format_type(rtype, generic_types)?)
}
Expand Down
3 changes: 3 additions & 0 deletions core/src/language/scala.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ impl Language for Scala {
SpecialRustType::Array(rtype, _) => {
format!("Vector[{}]", self.format_type(rtype, generic_types)?)
}
SpecialRustType::Slice(rtype) => {
format!("Vector[{}]", self.format_type(rtype, generic_types)?)
}
SpecialRustType::Option(rtype) => {
format!("Option[{}]", self.format_type(rtype, generic_types)?)
}
Expand Down
3 changes: 3 additions & 0 deletions core/src/language/swift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ impl Language for Swift {
SpecialRustType::Array(rtype, _) => {
format!("[{}]", self.format_type(rtype, generic_types)?)
}
SpecialRustType::Slice(rtype) => {
format!("[{}]", self.format_type(rtype, generic_types)?)
}
SpecialRustType::Option(rtype) => {
format!("{}?", self.format_type(rtype, generic_types)?)
}
Expand Down
3 changes: 3 additions & 0 deletions core/src/language/typescript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ impl Language for TypeScript {
.join_with(", ")
))
}
SpecialRustType::Slice(rtype) => {
Ok(format!("{}[]", self.format_type(rtype, generic_types)?))
}
// We add optionality above the type formatting level
SpecialRustType::Option(rtype) => self.format_type(rtype, generic_types),
SpecialRustType::HashMap(rtype1, rtype2) => Ok(format!(
Expand Down
17 changes: 14 additions & 3 deletions core/src/rust_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use quote::ToTokens;
use std::collections::BTreeSet;
use std::str::FromStr;
use std::{collections::HashMap, convert::TryFrom};
use syn::{Expr, ExprLit, Lit, TypeArray};
use syn::{Expr, ExprLit, Lit, TypeArray, TypeSlice};
use thiserror::Error;

use crate::language::SupportedLanguage;
Expand Down Expand Up @@ -135,6 +135,8 @@ pub enum SpecialRustType {
Vec(Box<RustType>),
/// Represents `[T; N]` from the standard library
Array(Box<RustType>, usize),
/// Represents `&[T]` from the standard library
Slice(Box<RustType>),
/// Represents `HashMap<K, V>` from the standard library
HashMap(Box<RustType>, Box<RustType>),
/// Represents `Option<T>` from the standard library
Expand Down Expand Up @@ -280,6 +282,12 @@ impl TryFrom<&syn::Type> for RustType {
.base10_parse()
.map_err(RustTypeParseError::NumericLiteral)?,
)),
syn::Type::Slice(TypeSlice {
bracket_token: _,
elem,
}) => Self::Special(SpecialRustType::Slice(
Self::try_from(elem.as_ref())?.into(),
)),
_ => {
return Err(RustTypeParseError::UnexpectedToken(
ty.to_token_stream().to_string(),
Expand Down Expand Up @@ -372,7 +380,9 @@ impl SpecialRustType {
/// Check if this type is equivalent to or contains `ty` in one of its generic parameters.
pub fn contains_type(&self, ty: &str) -> bool {
match &self {
Self::Vec(rty) | Self::Array(rty, _) | Self::Option(rty) => rty.contains_type(ty),
Self::Vec(rty) | Self::Array(rty, _) | Self::Slice(rty) | Self::Option(rty) => {
rty.contains_type(ty)
}
Self::HashMap(rty1, rty2) => rty1.contains_type(ty) || rty2.contains_type(ty),
Self::Unit
| Self::String
Expand Down Expand Up @@ -402,6 +412,7 @@ impl SpecialRustType {
Self::F32 => "f32",
Self::Vec(_) => "Vec",
Self::Array(_, _) => "[]",
Self::Slice(_) => "&[]",
Self::Option(_) => "Option",
Self::HashMap(_, _) => "HashMap",
Self::String => "String",
Expand All @@ -424,7 +435,7 @@ impl SpecialRustType {
/// if there are none.
pub fn parameters(&self) -> Box<dyn Iterator<Item = &RustType> + '_> {
match &self {
Self::Vec(rtype) | Self::Array(rtype, _) | Self::Option(rtype) => {
Self::Vec(rtype) | Self::Array(rtype, _) | Self::Slice(rtype) | Self::Option(rtype) => {
Box::new(std::iter::once(rtype.as_ref()))
}
Self::HashMap(rtype1, rtype2) => {
Expand Down
1 change: 1 addition & 0 deletions core/tests/snapshot_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ tests! {
scala,
typescript
];
can_generate_slice_of_user_type: [swift, kotlin, scala, typescript, go];
can_generate_readonly_fields: [
typescript
];
Expand Down

0 comments on commit 0b8bb7b

Please sign in to comment.