Skip to content

Commit

Permalink
[typeshare] Support external tags for enums (#7)
Browse files Browse the repository at this point in the history
## Description
* For complex enums the default serde serialization is externally tagged, to avoid having to re-write our rust logic to use internal tags via `#[serde(tag = "type", content = "content")]` we are going to add manual support for it in `typescript`
* Bumping version to `1.12.1`
* Adding a `--dry-run` flag to allow building locally

### Before
```
# Rust
enum MyEnum {
  blahblah {
    name: String
  }
  blahblah2 {
    age: u64
  }
}
```

```
# Typescript
export type MyEnum = 
  { "type": "blahblah", content: { "name": string }}
  | { "type": "blahblah2", content: { "age": number }}
```

### After
```
export type MyEnum =
 { "blahblah": { "name": string }}
| { "blahblah2": { "age": number }}
```

## Test Plan
* CI passes

## Revert Plan
* Revert
  • Loading branch information
naveenOnarayanan authored Nov 7, 2024
1 parent a8ea230 commit 49b811a
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 39 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ dist/
uploads.txt
dist-manifest.json
.intentionally-empty-file.o
.DS_Store
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "typeshare-cli"
version = "1.12.0"
version = "1.12.1"
edition = "2021"
description = "Command Line Tool for generating language files with typeshare"
license = "MIT OR Apache-2.0"
Expand All @@ -26,7 +26,7 @@ once_cell = "1"
rayon = "1.10"
serde = { version = "1", features = ["derive"] }
toml = "0.8"
typeshare-core = { path = "../core", version = "=1.12.0" }
typeshare-core = { path = "../core", version = "=1.12.1" }
log.workspace = true
flexi_logger.workspace = true
anyhow = "1"
Expand Down
2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "typeshare-core"
version = "1.12.0"
version = "1.12.1"
license = "MIT OR Apache-2.0"
edition = "2021"
description = "The code generator used by Typeshare's command line tool"
Expand Down
71 changes: 51 additions & 20 deletions core/src/language/typescript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,32 +216,63 @@ impl TypeScript {
writeln!(w)?;
self.write_comments(w, 1, &v.shared().comments)?;
match v {
RustEnumVariant::Unit(shared) => write!(
w,
"\t| {{ {}: {:?}, {}?: undefined }}",
tag_key, shared.id.renamed, content_key
),
RustEnumVariant::Unit(shared) => {
if !tag_key.is_empty() {
if !content_key.is_empty() {
write!(
w,
"\t| {{ {}: {:?}, {}?: undefined }}",
tag_key, shared.id.renamed, content_key
)
} else {
write!(w, "\t| {{ {}: {:?} }}", tag_key, shared.id.renamed)
}
} else {
write!(w, "\t| {:?}", shared.id.renamed)
}
}
RustEnumVariant::Tuple { ty, shared } => {
let r#type = self
.format_type(ty, e.shared().generic_types.as_slice())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
write!(
w,
"\t| {{ {}: {:?}, {}{}: {} }}",
tag_key,
shared.id.renamed,
content_key,
ty.is_optional().then_some("?").unwrap_or_default(),
r#type
)
if !tag_key.is_empty() {
if !content_key.is_empty() {
write!(
w,
"\t| {{ {}: {:?}, {}{}: {} }}",
tag_key,
shared.id.renamed,
content_key,
ty.is_optional().then_some("?").unwrap_or_default(),
r#type
)
} else {
panic!("Tuple variants must have a content key if they have a tag key: {:?}", shared.id.original)
}
} else {
write!(
w,
"\t| {{ {:?}{}: {} }}",
shared.id.renamed,
ty.is_optional().then_some("?").unwrap_or_default(),
r#type
)
}
}
RustEnumVariant::AnonymousStruct { fields, shared } => {
writeln!(
w,
"\t| {{ {}: {:?}, {}: {{",
tag_key, shared.id.renamed, content_key
)?;

if !tag_key.is_empty() {
if !content_key.is_empty() {
writeln!(
w,
"\t| {{ {}: {:?}, {}: {{",
tag_key, shared.id.renamed, content_key
)?;
} else {
panic!("Struct variants must have a content key if they have a tag key: {:?}", shared.id.original)
}
} else {
writeln!(w, "\t| {{ {:?}: {{", shared.id.renamed)?;
}
fields.iter().try_for_each(|f| {
self.write_field(w, f, e.shared().generic_types.as_slice())
})?;
Expand Down
8 changes: 2 additions & 6 deletions core/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,12 +391,8 @@ pub(crate) fn parse_enum(e: &ItemEnum, target_os: &[String]) -> Result<RustItem,
} else {
// At least one enum variant is either a tuple or an anonymous struct

let tag_key = maybe_tag_key.ok_or_else(|| ParseError::SerdeTagRequired {
enum_ident: original_enum_ident.clone(),
})?;
let content_key = maybe_content_key.ok_or_else(|| ParseError::SerdeContentRequired {
enum_ident: original_enum_ident.clone(),
})?;
let tag_key = maybe_tag_key.unwrap_or_default();
let content_key = maybe_content_key.unwrap_or_default();

Ok(RustItem::Enum(RustEnum::Algebraic {
tag_key,
Expand Down
27 changes: 19 additions & 8 deletions scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ function help() {
echo " * \"aarch64-unknown-linux-gnu\""
echo " * \"x86_64-unknown-linux-gnu\""
echo " * \"x86_64-pc-windows-msvc\""
echo " --dry-run Run the script without releasing"
exit 0
}

Expand All @@ -26,6 +27,8 @@ function help() {
TARGET=""
# --version <version>
VERSION=""
# --dry-run
DRY_RUN=false

# Parse command line arguments
while [[ $# -gt 0 ]]; do
Expand All @@ -41,6 +44,10 @@ while [[ $# -gt 0 ]]; do
shift
shift
;;
--dry-run)
DRY_RUN=true
shift
;;
-h|--help)
help
;;
Expand All @@ -52,12 +59,12 @@ while [[ $# -gt 0 ]]; do
done

# Check if required arguments are provided
if [ -z "${TARGET}" ]; then
if [[ -z "${TARGET}" ]]; then
echo "Missing required argument: --target"
exit 1
fi

if [ -z "$VERSION" ]; then
if [[ -z "$VERSION" ]]; then
echo "Missing required argument: --version"
exit 1
fi
Expand Down Expand Up @@ -87,9 +94,13 @@ echo "{\"artifacts\": [{\"path\": \"dist/${ZIP_NAME}\"}]}" > dist-manifest.json
echo "Build complete, contents of dist-manifest.json:"
cat dist-manifest.json

# Upload to release
cat dist-manifest.json | jq --raw-output ".artifacts[]?.path | select( . != null )" > uploads.txt
echo "uploading..."
cat uploads.txt
gh release upload ${VERSION} $(cat uploads.txt)
echo "uploaded!"
if [[ "$DRY_RUN" == true ]]; then
echo "ℹ️ Dry run, skipping release upload"
else
# Upload to release
cat dist-manifest.json | jq --raw-output ".artifacts[]?.path | select( . != null )" > uploads.txt
echo "uploading..."
cat uploads.txt
gh release upload ${VERSION} $(cat uploads.txt)
echo "uploaded!"
fi

0 comments on commit 49b811a

Please sign in to comment.