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

Write out types in topological order #62

Merged
merged 10 commits into from
Mar 30, 2023
10 changes: 5 additions & 5 deletions core/data/tests/can_generate_generic_enum/output.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ package com.agilebits.onepassword
import androidx.compose.runtime.NoLiveLiterals
import kotlinx.serialization.*

@Serializable
data class StructUsingGenericEnum (
val enum_field: GenericEnum<String, Short>
)

@Serializable
sealed class GenericEnum<A, B> {
@Serializable
Expand All @@ -20,6 +15,11 @@ sealed class GenericEnum<A, B> {
data class VariantB<A, B>(val content: B): GenericEnum<A, B>()
}

@Serializable
data class StructUsingGenericEnum (
val enum_field: GenericEnum<String, Short>
)

@Serializable
sealed class GenericEnumUsingGenericEnum<T> {
@Serializable
Expand Down
16 changes: 8 additions & 8 deletions core/data/tests/can_generate_generic_enum/output.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
import Foundation

public struct CoreStructUsingGenericEnum: Codable {
public let enum_field: CoreGenericEnum<String, Int16>

public init(enum_field: CoreGenericEnum<String, Int16>) {
self.enum_field = enum_field
}
}

public enum CoreGenericEnum<A: Codable, B: Codable>: Codable {
case variantA(A)
case variantB(B)
Expand Down Expand Up @@ -53,6 +45,14 @@ public enum CoreGenericEnum<A: Codable, B: Codable>: Codable {
}
}

public struct CoreStructUsingGenericEnum: Codable {
public let enum_field: CoreGenericEnum<String, Int16>

public init(enum_field: CoreGenericEnum<String, Int16>) {
self.enum_field = enum_field
}
}

public enum CoreGenericEnumUsingGenericEnum<T: Codable>: Codable {
case variantC(CoreGenericEnum<T, T>)
case variantD(CoreGenericEnum<String, [String: T]>)
Expand Down
8 changes: 4 additions & 4 deletions core/data/tests/can_generate_generic_enum/output.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export interface StructUsingGenericEnum {
enum_field: GenericEnum<string, number>;
}

export type GenericEnum<A, B> =
| { type: "VariantA", content: A }
| { type: "VariantB", content: B };

export interface StructUsingGenericEnum {
enum_field: GenericEnum<string, number>;
}

export type GenericEnumUsingGenericEnum<T> =
| { type: "VariantC", content: GenericEnum<T, T> }
| { type: "VariantD", content: GenericEnum<string, Record<string, T>> }
Expand Down
31 changes: 31 additions & 0 deletions core/data/tests/orders_types/input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#[typeshare]
#[serde(rename_all = "camelCase")]
pub struct E {
depends_on: D,
}

#[typeshare]
#[serde(rename_all = "camelCase")]
pub struct D {
depends_on: C,
also_depends_on: Option<E>,
}

#[typeshare]
#[serde(rename_all = "camelCase")]
pub struct C {
depends_on: B
}

#[typeshare]
#[serde(rename_all = "camelCase")]
pub struct B {
depends_on: A,
}

#[typeshare]
#[serde(rename_all = "camelCase")]
pub struct A {
field: u32
}

20 changes: 20 additions & 0 deletions core/data/tests/orders_types/output.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package proto

import "encoding/json"

type A struct {
Field uint32 `json:"field"`
}
type B struct {
DependsOn A `json:"dependsOn"`
}
type C struct {
DependsOn B `json:"dependsOn"`
}
type D struct {
DependsOn C `json:"dependsOn"`
AlsoDependsOn *E `json:"alsoDependsOn,omitempty"`
}
type E struct {
DependsOn D `json:"dependsOn"`
}
33 changes: 33 additions & 0 deletions core/data/tests/orders_types/output.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@file:NoLiveLiterals

package com.agilebits.onepassword

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

@Serializable
data class A (
val field: UInt
)

@Serializable
data class B (
val dependsOn: A
)

@Serializable
data class C (
val dependsOn: B
)

@Serializable
data class D (
val dependsOn: C,
val alsoDependsOn: E? = null
)

@Serializable
data class E (
val dependsOn: D
)

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

public struct A: Codable {
public let field: UInt32

public init(field: UInt32) {
self.field = field
}
}

public struct B: Codable {
public let dependsOn: A

public init(dependsOn: A) {
self.dependsOn = dependsOn
}
}

public struct C: Codable {
public let dependsOn: B

public init(dependsOn: B) {
self.dependsOn = dependsOn
}
}

public struct D: Codable {
public let dependsOn: C
public let alsoDependsOn: E?

public init(dependsOn: C, alsoDependsOn: E?) {
self.dependsOn = dependsOn
self.alsoDependsOn = alsoDependsOn
}
}

public struct E: Codable {
public let dependsOn: D

public init(dependsOn: D) {
self.dependsOn = dependsOn
}
}
21 changes: 17 additions & 4 deletions core/src/language/go.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ use std::io::Write;

use crate::parser::ParsedData;
use crate::rename::RenameExt;
use crate::rust_types::{RustTypeFormatError, SpecialRustType};
use crate::rust_types::{RustItem, RustTypeFormatError, SpecialRustType};
use crate::{
language::Language,
rust_types::{RustEnum, RustEnumVariant, RustField, RustStruct, RustTypeAlias},
topsort::topsort,
};
use std::collections::{HashMap, HashSet};

Expand Down Expand Up @@ -39,16 +40,28 @@ impl Language for Go {

self.begin_file(w)?;

let mut items: Vec<RustItem> = vec![];

for a in &data.aliases {
self.write_type_alias(w, a)?;
items.push(RustItem::Alias(a.clone()))
}

for s in &data.structs {
self.write_struct(w, s)?;
items.push(RustItem::Struct(s.clone()))
}

for e in &data.enums {
self.write_enum(w, e, &types_mapping_to_struct)?;
items.push(RustItem::Enum(e.clone()))
}

let sorted = topsort(items.iter().collect());

for &thing in &sorted {
match thing {
RustItem::Enum(e) => self.write_enum(w, e, &types_mapping_to_struct)?,
RustItem::Struct(s) => self.write_struct(w, s)?,
RustItem::Alias(a) => self.write_type_alias(w, a)?,
}
}

self.end_file(w)?;
Expand Down
21 changes: 17 additions & 4 deletions core/src/language/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
parser::{ParseError, ParsedData},
rust_types::{Id, RustEnum, RustEnumVariant, RustStruct, RustTypeAlias},
rust_types::{Id, RustEnum, RustEnumVariant, RustItem, RustStruct, RustTypeAlias},
topsort::topsort,
};
use itertools::Itertools;
use proc_macro2::Ident;
Expand Down Expand Up @@ -68,16 +69,28 @@ pub trait Language {
) -> std::io::Result<()> {
self.begin_file(writable)?;

let mut items: Vec<RustItem> = vec![];

for a in &data.aliases {
self.write_type_alias(writable, a)?;
items.push(RustItem::Alias(a.clone()))
}

for s in &data.structs {
self.write_struct(writable, s)?;
items.push(RustItem::Struct(s.clone()))
}

for e in &data.enums {
self.write_enum(writable, e)?;
items.push(RustItem::Enum(e.clone()))
}

let sorted = topsort(items.iter().collect());

for &thing in &sorted {
match thing {
RustItem::Enum(e) => self.write_enum(writable, e)?,
RustItem::Struct(s) => self.write_struct(writable, s)?,
RustItem::Alias(a) => self.write_type_alias(writable, a)?,
}
}

self.end_file(writable)?;
Expand Down
1 change: 1 addition & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod language;
pub mod parser;
/// Codifying Rust types and how they convert to various languages.
pub mod rust_types;
mod topsort;

#[derive(Debug, Error)]
#[allow(missing_docs)]
Expand Down
Loading