Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[typeshare] Support linux-arm64 and support u64 #1

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,23 @@ jobs:
include:
- os: ubuntu-20.04
dist-args: --artifacts=global
target: ''
install-dist: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.4/cargo-dist-v0.0.4-installer.sh | sh
- os: macos-11
dist-args: --artifacts=local --target=aarch64-apple-darwin --target=x86_64-apple-darwin
target: 'aarch64-apple-darwin x86_64-apple-darwin'
install-dist: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.4/cargo-dist-v0.0.4-installer.sh | sh
- os: ubuntu-20.04
dist-args: --artifacts=local --target=x86_64-unknown-linux-gnu
target: 'x86_64-unknown-linux-gnu'
install-dist: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.4/cargo-dist-v0.0.4-installer.sh | sh
- os: ubuntu-20.04
dist-args: --artifacts=local --target=aarch64-unknown-linux-gnu
target: 'aarch64-unknown-linux-gnu'
install-dist: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.4/cargo-dist-v0.0.4-installer.sh | sh
- os: windows-2019
dist-args: --artifacts=local --target=x86_64-pc-windows-msvc
target: 'x86_64-pc-windows-msvc'
install-dist: irm https://github.com/axodotdev/cargo-dist/releases/download/v0.0.4/cargo-dist-v0.0.4-installer.ps1 | iex

runs-on: ${{ matrix.os }}
Expand All @@ -108,17 +116,36 @@ jobs:
- name: Install cargo-dist
run: ${{ matrix.install-dist }}
- name: Run cargo-dist
if: ${{ matrix.target != '' }}
# This logic is a bit janky because it's trying to be a polyglot between
# powershell and bash since this will run on windows, macos, and linux!
# The two platforms don't agree on how to talk about env vars but they
# do agree on 'cat' and '$()' so we use that to marshal values between commands.
run: |
# Actually do builds and make zips and whatnot
cargo dist build --tag=${{ github.ref_name }} --output-format=json ${{ matrix.dist-args }} > dist-manifest.json
echo "dist ran successfully"
pip3 install ziglang
cargo install cargo-zigbuild
rustup target add ${{ matrix.target }}
cargo zigbuild --target ${{ matrix.target }} --release

# Set binary name to typeshare
BINARY_NAME="typeshare"
TARGET_DIR="target/${{ matrix.target }}/release"

# Create zip directory
mkdir -p "dist"

# Create zip file with binary
ZIP_NAME="${BINARY_NAME}-${{ github.ref_name }}-${{ matrix.target }}.zip"
cd ${TARGET_DIR} && zip "../../../dist/${ZIP_NAME}" "${BINARY_NAME}${BINARY_SUFFIX}"
cd ../../..

# Create manifest file similar to cargo-dist
echo "{\"artifacts\": [{\"path\": \"dist/${ZIP_NAME}\"}]}" > dist-manifest.json

echo "Build complete, contents of dist-manifest.json:"
cat dist-manifest.json

# Parse out what we just built and upload it to the Github Release™
# Upload to release
cat dist-manifest.json | jq --raw-output ".artifacts[]?.path | select( . != null )" > uploads.txt
echo "uploading..."
cat uploads.txt
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ ci = ["github"]
installers = ["shell", "powershell"]
# Target platforms to build apps for (Rust target-triple syntax)
targets = [
"aarch64-unknown-linux-gnu",
"x86_64-unknown-linux-gnu",
"x86_64-apple-darwin",
"x86_64-pc-windows-msvc",
Expand Down
10 changes: 10 additions & 0 deletions core/data/tests/can_override_disallowed_types/input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#[typeshare]
struct DisallowedType {
#[typeshare(typescript(type = "bigint"))]
disallowed_type: u64,
#[typeshare(typescript(type = "number"))]
another_disallowed_type: i64,
#[typeshare(typescript(type = "string"))]
#[serde(with = "my_string_serde_impl")]
disallowed_type_serde_with: u64,
}
9 changes: 9 additions & 0 deletions core/data/tests/can_override_disallowed_types/output.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package proto

import "encoding/json"

type DisallowedType struct {
DisallowedType uint64 `json:"disallowed_type"`
AnotherDisallowedType int64 `json:"another_disallowed_type"`
DisallowedTypeSerdeWith uint64 `json:"disallowed_type_serde_with"`
}
12 changes: 12 additions & 0 deletions core/data/tests/can_override_disallowed_types/output.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.agilebits.onepassword

import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName

@Serializable
data class DisallowedType (
val disallowed_type: ULong,
val another_disallowed_type: Long,
val disallowed_type_serde_with: ULong
)

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

package object onepassword {

type UByte = Byte
type UShort = Short
type UInt = Int
type ULong = Int

}
package onepassword {

case class DisallowedType (
disallowed_type: ULong,
another_disallowed_type: Long,
disallowed_type_serde_with: ULong
)

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

public struct DisallowedType: Codable {
public let disallowed_type: UInt64
public let another_disallowed_type: Int64
public let disallowed_type_serde_with: UInt64

public init(disallowed_type: UInt64, another_disallowed_type: Int64, disallowed_type_serde_with: UInt64) {
self.disallowed_type = disallowed_type
self.another_disallowed_type = another_disallowed_type
self.disallowed_type_serde_with = disallowed_type_serde_with
}
}
6 changes: 6 additions & 0 deletions core/data/tests/can_override_disallowed_types/output.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface DisallowedType {
disallowed_type: bigint;
another_disallowed_type: number;
disallowed_type_serde_with: string;
}

1 change: 1 addition & 0 deletions core/src/language/go.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ impl Language for Go {
SpecialRustType::U32 => "uint32".into(),
SpecialRustType::I54 | SpecialRustType::I64 => "int64".into(),
SpecialRustType::U53 | SpecialRustType::U64 => "uint64".into(),
SpecialRustType::U128 => "uint128".into(),
SpecialRustType::Bool => "bool".into(),
SpecialRustType::F32 => "float32".into(),
SpecialRustType::F64 => "float64".into(),
Expand Down
1 change: 1 addition & 0 deletions core/src/language/kotlin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ impl Language for Kotlin {
SpecialRustType::Bool => "Boolean".into(),
SpecialRustType::F32 => "Float".into(),
SpecialRustType::F64 => "Double".into(),
SpecialRustType::U128 => "BigInteger".into(),
})
}

Expand Down
1 change: 1 addition & 0 deletions core/src/language/scala.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ impl Language for Scala {
SpecialRustType::Bool => "Boolean".into(),
SpecialRustType::F32 => "Float".into(),
SpecialRustType::F64 => "Double".into(),
SpecialRustType::U128 => "BigInt".into(),
})
}

Expand Down
1 change: 1 addition & 0 deletions core/src/language/swift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ impl Language for Swift {
SpecialRustType::Bool => "Bool".into(),
SpecialRustType::F32 => "Float".into(),
SpecialRustType::F64 => "Double".into(),
SpecialRustType::U128 => "UInt128".into(),
})
}

Expand Down
8 changes: 4 additions & 4 deletions core/src/language/typescript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,8 @@ impl Language for TypeScript {
SpecialRustType::U64
| SpecialRustType::I64
| SpecialRustType::ISize
| SpecialRustType::USize => {
panic!("64 bit types not allowed in Typeshare")
}
| SpecialRustType::U128
| SpecialRustType::USize => Ok("number".into())
}
}

Expand Down Expand Up @@ -178,8 +177,9 @@ impl Language for TypeScript {
w: &mut dyn Write,
imports: ScopedCrateTypes<'_>,
) -> std::io::Result<()> {
writeln!(w, "import type {{ HashSet }} from \"./base\";")?;
for (path, ty) in imports {
write!(w, "import {{ ")?;
write!(w, "import type {{ ")?;
let ty_list = ty.iter().join(", ");
write!(w, "{ty_list}")?;
writeln!(w, " }} from \"./{path}\";")?;
Expand Down
15 changes: 12 additions & 3 deletions core/src/rust_types.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use log::debug;
use quote::ToTokens;
use std::collections::BTreeSet;
use std::str::FromStr;
Expand Down Expand Up @@ -206,6 +207,8 @@ pub enum SpecialRustType {
I32,
/// Represents `i64`
I64,
/// Represents `u128`
U128,
/// Represents `u8`
U8,
/// Represents `u16`
Expand Down Expand Up @@ -257,6 +260,7 @@ impl TryFrom<&syn::Type> for RustType {
type Error = RustTypeParseError;

fn try_from(ty: &syn::Type) -> Result<Self, Self::Error> {
debug!("Parsing type: {}", ty.to_token_stream());
Ok(match ty {
syn::Type::Tuple(tuple) if tuple.elems.iter().count() == 0 => {
Self::Special(SpecialRustType::Unit)
Expand Down Expand Up @@ -305,12 +309,14 @@ impl TryFrom<&syn::Type> for RustType {
"u16" => Self::Special(SpecialRustType::U16),
"u32" => Self::Special(SpecialRustType::U32),
"U53" => Self::Special(SpecialRustType::U53),
"u64" | "i64" | "usize" | "isize" => {
return Err(RustTypeParseError::UnsupportedType(vec![id]))
}
"u64" => Self::Special(SpecialRustType::U64),
"usize" => Self::Special(SpecialRustType::USize),
"u128" => Self::Special(SpecialRustType::U128),
"i8" => Self::Special(SpecialRustType::I8),
"i16" => Self::Special(SpecialRustType::I16),
"i32" => Self::Special(SpecialRustType::I32),
"i64" => Self::Special(SpecialRustType::I64),
"isize" => Self::Special(SpecialRustType::ISize),
"I54" => Self::Special(SpecialRustType::I54),
"f32" => Self::Special(SpecialRustType::F32),
"f64" => Self::Special(SpecialRustType::F64),
Expand Down Expand Up @@ -488,6 +494,7 @@ impl SpecialRustType {
| Self::F32
| Self::F64
| Self::I54
| Self::U128
| Self::U53 => ty == self.id(),
}
}
Expand Down Expand Up @@ -518,6 +525,7 @@ impl SpecialRustType {
Self::USize => "usize",
Self::U53 => "U53",
Self::I54 => "I54",
Self::U128 => "u128",
}
}
/// Iterate over the generic parameters for this type. Returns an empty iterator
Expand All @@ -541,6 +549,7 @@ impl SpecialRustType {
| Self::U16
| Self::U32
| Self::U64
| Self::U128
| Self::ISize
| Self::USize
| Self::Bool
Expand Down
15 changes: 11 additions & 4 deletions core/src/visitors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,33 +265,38 @@ impl<'ast, 'a> Visit<'ast> for TypeShareVisitor<'a> {

/// Collect rust structs.
fn visit_item_struct(&mut self, i: &'ast syn::ItemStruct) {
debug!("Visiting {}", i.ident);
debug!("Visiting item {}", i.ident);
if has_typeshare_annotation(&i.attrs) && self.target_os_accepted(&i.attrs) {
debug!("\tParsing {}", i.ident);
self.collect_result(parse_struct(i, self.target_os));
debug!("\tParsed {}", i.ident);
}

debug!("Visited item {}", i.ident);
syn::visit::visit_item_struct(self, i);
}

/// Collect rust enums.
fn visit_item_enum(&mut self, i: &'ast syn::ItemEnum) {
debug!("Visiting {}", i.ident);
debug!("Visiting enum {}", i.ident);
if has_typeshare_annotation(&i.attrs) && self.target_os_accepted(&i.attrs) {
debug!("\tParsing {}", i.ident);
self.collect_result(parse_enum(i, self.target_os));
debug!("\tParsed {}", i.ident);
}
debug!("Visited enum {}", i.ident);

syn::visit::visit_item_enum(self, i);
}

/// Collect rust type aliases.
fn visit_item_type(&mut self, i: &'ast syn::ItemType) {
debug!("Visiting {}", i.ident);
debug!("Visiting type {}", i.ident);
if has_typeshare_annotation(&i.attrs) && self.target_os_accepted(&i.attrs) {
debug!("\tParsing {}", i.ident);
self.collect_result(parse_type_alias(i));
debug!("\tParsed {}", i.ident);
}
debug!("Visited type {}", i.ident);

syn::visit::visit_item_type(self, i);
}
Expand All @@ -308,9 +313,11 @@ impl<'ast, 'a> Visit<'ast> for TypeShareVisitor<'a> {
// }

fn visit_file(&mut self, i: &'ast syn::File) {
debug!("Visiting file {}", self.parsed_data.file_name);
if self.target_os_accepted(&i.attrs) {
syn::visit::visit_file(self, i);
}
debug!("Visited file {}", self.parsed_data.file_name);
}
}

Expand Down
63 changes: 0 additions & 63 deletions core/tests/agnostic_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::io::Write;
use typeshare_core::{
language::{CrateTypes, Language, TypeScript},
parser::{self, ParseError},
rust_types::RustTypeParseError,
ProcessInputError,
};
/// Parse and generate types for a single Rust input file.
Expand Down Expand Up @@ -33,68 +32,6 @@ pub fn process_input(
Ok(())
}

mod blocklisted_types {
use std::collections::HashMap;

use super::*;

fn assert_type_is_blocklisted(ty: &str, blocklisted_type: &str) {
let source = format!(
r##"
#[typeshare]
#[serde(default, rename_all = "camelCase")]
pub struct Foo {{
pub bar: {ty},
}}
"##,
ty = ty
);

let mut out: Vec<u8> = Vec::new();
assert!(matches!(
process_input(&source, &mut TypeScript::default(), &HashMap::new(), &mut out),
Err(ProcessInputError::ParseError(
ParseError::RustTypeParseError(RustTypeParseError::UnsupportedType(contents))
)) if contents == vec![blocklisted_type.to_owned()]
));
}

#[test]
fn test_i64_blocklisted_struct() {
assert_type_is_blocklisted("i64", "i64");
}

#[test]
fn test_u64_blocklisted_struct() {
assert_type_is_blocklisted("u64", "u64");
}

#[test]
fn test_isize_blocklisted_struct() {
assert_type_is_blocklisted("isize", "isize");
}

#[test]
fn test_usize_blocklisted_in_struct() {
assert_type_is_blocklisted("usize", "usize");
}

#[test]
fn test_optional_blocklisted_struct() {
assert_type_is_blocklisted("Option<i64>", "i64");
}

#[test]
fn test_vec_blocklisted_struct() {
assert_type_is_blocklisted("Vec<i64>", "i64");
}

#[test]
fn test_hashmap_blocklisted_struct() {
assert_type_is_blocklisted("HashMap<String, i64>", "i64");
}
}

mod serde_attributes_on_enums {
use std::collections::HashMap;

Expand Down
Loading