Skip to content

Commit

Permalink
fixes #201 - export Typescript function header
Browse files Browse the repository at this point in the history
  • Loading branch information
oscartbeaumont committed Dec 24, 2023
1 parent 48b86ae commit 253fc44
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/lang/ts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub use export_config::*;
use reserved_terms::*;

use crate::{
functions::FunctionDataType,
internal::{skip_fields, skip_fields_named, NonSkipField},
*,
};
Expand Down Expand Up @@ -91,6 +92,53 @@ pub fn export_named_datatype(
)
}

/// Convert a [FunctionDataType] into a function header like would be used in a `.d.ts` file.
/// If your function requires a function body you can copy this function into your own codebase.
///
/// Eg. `function name();`
pub fn export_function_header(dt: FunctionDataType, config: &ExportConfig) -> Result<String> {
let type_map = TypeMap::default();

let mut s = config
.comment_exporter
.map(|v| {
v(CommentFormatterArgs {
docs: &dt.docs,
deprecated: dt.deprecated.as_ref(),
})
})
.unwrap_or_default();

s.push_str("export ");

if dt.asyncness {
s.push_str("async ");
}

s.push_str("function ");

s.push_str(&dt.name);
s.push_str("(");

Check warning on line 121 in src/lang/ts/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

calling `push_str()` using a single-character string literal

warning: calling `push_str()` using a single-character string literal --> src/lang/ts/mod.rs:121:5 | 121 | s.push_str("("); | ^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `s.push('(')` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_char_add_str = note: `#[warn(clippy::single_char_add_str)]` implied by `#[warn(clippy::all)]`
for (i, (name, ty)) in dt.args.into_iter().enumerate() {
if i != 0 {
s.push_str(", ");
}

s.push_str(&name);
s.push_str(": ");
s.push_str(&datatype(config, &ty, &type_map)?);
}
s.push_str(")");

Check warning on line 131 in src/lang/ts/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

calling `push_str()` using a single-character string literal

warning: calling `push_str()` using a single-character string literal --> src/lang/ts/mod.rs:131:5 | 131 | s.push_str(")"); | ^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `s.push(')')` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_char_add_str

if let Some(ty) = dt.result {
s.push_str(": ");
s.push_str(&datatype(config, &ty, &type_map)?);
}

s.push_str(";");

Check warning on line 138 in src/lang/ts/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

calling `push_str()` using a single-character string literal

warning: calling `push_str()` using a single-character string literal --> src/lang/ts/mod.rs:138:5 | 138 | s.push_str(";"); | ^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `s.push(';')` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_char_add_str
Ok(s)
}

#[allow(clippy::ptr_arg)]
fn inner_comments(
ctx: ExportContext,
Expand Down
1 change: 1 addition & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub mod ts;
mod ts_rs;
mod ty_override;
mod type_map;
mod typescript;
#[cfg(all(feature = "ulid", feature = "typescript"))]
mod ulid;

Expand Down
46 changes: 46 additions & 0 deletions tests/typescript/export_function_header.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#![allow(deprecated)]

use specta::{fn_datatype, functions::FunctionDataType, specta, ts::export_function_header};

#[specta]
fn a() {}
#[specta]
fn b() -> () {}
#[specta]
async fn c() {}
#[specta]
fn d() -> String {
"todo".into()
}
#[specta]
fn e(a: String) {}
#[specta]
fn f(a: String, b: i32) {}
#[specta]
#[deprecated]
fn g() {}

#[test]
fn test_export_function_header() {
assert(fn_datatype!(a), Ok("export function a();"));
assert(fn_datatype!(b), Ok("export function b(): null;"));
assert(fn_datatype!(c), Ok("export async function c();"));
assert(fn_datatype!(d), Ok("export function d(): string;"));
assert(fn_datatype!(e), Ok("export function e(a: string);"));
assert(
fn_datatype!(f),
Ok("export function f(a: string, b: number);"),
);
assert(
fn_datatype!(g),
Ok("/**\n * @deprecated\n */\nexport function g();"),
);
}

#[track_caller]
fn assert(dt: FunctionDataType, result: specta::ts::Result<&str>) {
match export_function_header(dt, &Default::default()) {
Ok(s) => assert_eq!(result, Ok(s.as_str())),
Err(e) => assert_eq!(result, Err(e)),
}
}
1 change: 1 addition & 0 deletions tests/typescript/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod export_function_header;

0 comments on commit 253fc44

Please sign in to comment.