use crate::{Export, Function, Language, TypeDef};
pub const MAX_DEFINITION_SNIPPET_LINES: usize = 10;
#[must_use]
pub fn function_definition_snippet(f: &Function, lang: Language) -> String {
let vis = lang.visibility_keyword(f.is_public);
let async_kw = if f.is_async { "async " } else { "" };
let fn_kw = lang.function_keyword();
let params = f.parameters.join(", ");
format!("{vis}{async_kw}{fn_kw} {}({params})", f.name)
}
#[must_use]
pub fn type_definition_snippet(t: &TypeDef, lang: Language) -> String {
let vis = lang.visibility_keyword(t.is_public);
format!("{vis}{} {}", t.kind.keyword(), t.name)
}
#[must_use]
pub fn export_definition_snippet(e: &Export, lang: Language) -> String {
match lang {
Language::Rust => format!("pub use {}", e.name),
Language::TypeScript | Language::JavaScript => {
let default = if e.is_default { "default " } else { "" };
let type_only = if e.is_type_only { "type " } else { "" };
format!("export {default}{type_only}{}", e.name)
}
Language::Python => e.name.clone(),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::TypeDefKind;
fn mk_fn(name: &str, is_public: bool, is_async: bool, params: Vec<&str>) -> Function {
Function {
name: name.to_owned(),
is_public,
is_async,
line: 1,
end_line: 1,
parameters: params.into_iter().map(str::to_owned).collect(),
doc_comment: None,
}
}
fn mk_type(name: &str, kind: TypeDefKind, is_public: bool) -> TypeDef {
TypeDef {
name: name.to_owned(),
kind,
is_public,
line: 1,
end_line: 1,
doc_comment: None,
}
}
fn mk_export(name: &str, is_default: bool, is_type_only: bool) -> Export {
Export {
name: name.to_owned(),
is_default,
is_type_only,
line: 1,
end_line: 1,
}
}
#[test]
fn rust_function_pub_and_async() {
let f = mk_fn("foo", true, true, vec!["a", "b"]);
assert_eq!(
function_definition_snippet(&f, Language::Rust),
"pub async fn foo(a, b)"
);
}
#[test]
fn rust_function_private_sync() {
let f = mk_fn("bar", false, false, vec![]);
assert_eq!(function_definition_snippet(&f, Language::Rust), "fn bar()");
}
#[test]
fn typescript_function_export_async() {
let f = mk_fn("handle", true, true, vec!["req"]);
assert_eq!(
function_definition_snippet(&f, Language::TypeScript),
"export async function handle(req)"
);
}
#[test]
fn javascript_function_no_export() {
let f = mk_fn("helper", false, false, vec![]);
assert_eq!(
function_definition_snippet(&f, Language::JavaScript),
"function helper()"
);
}
#[test]
fn python_function_async_no_vis_keyword() {
let private = mk_fn("_helper", false, false, vec![]);
let async_pub = mk_fn("handler", true, true, vec!["req"]);
assert_eq!(
function_definition_snippet(&private, Language::Python),
"def _helper()"
);
assert_eq!(
function_definition_snippet(&async_pub, Language::Python),
"async def handler(req)"
);
}
#[test]
fn rust_type_struct_pub() {
let t = mk_type("Foo", TypeDefKind::Struct, true);
assert_eq!(
type_definition_snippet(&t, Language::Rust),
"pub struct Foo"
);
}
#[test]
fn rust_type_alias_private_renders_as_type_not_typealias() {
let t = mk_type("Alias", TypeDefKind::TypeAlias, false);
assert_eq!(type_definition_snippet(&t, Language::Rust), "type Alias");
}
#[test]
fn typescript_type_interface_export() {
let t = mk_type("Handle", TypeDefKind::Interface, true);
assert_eq!(
type_definition_snippet(&t, Language::TypeScript),
"export interface Handle"
);
}
#[test]
fn typescript_type_alias_export() {
let t = mk_type("Id", TypeDefKind::TypeAlias, true);
assert_eq!(
type_definition_snippet(&t, Language::TypeScript),
"export type Id"
);
}
#[test]
fn javascript_class_export() {
let t = mk_type("Foo", TypeDefKind::Class, true);
assert_eq!(
type_definition_snippet(&t, Language::JavaScript),
"export class Foo"
);
}
#[test]
fn python_class_no_vis_keyword() {
let t = mk_type("Foo", TypeDefKind::Class, false);
assert_eq!(type_definition_snippet(&t, Language::Python), "class Foo");
}
#[test]
fn rust_export_renders_as_pub_use() {
let e = mk_export("ApiHandle", false, false);
assert_eq!(
export_definition_snippet(&e, Language::Rust),
"pub use ApiHandle"
);
}
#[test]
fn rust_export_ignores_default_and_type_only_flags() {
let e = mk_export("Foo", true, true);
assert_eq!(export_definition_snippet(&e, Language::Rust), "pub use Foo");
}
#[test]
fn typescript_export_default_type_only() {
let e = mk_export("Foo", true, true);
assert_eq!(
export_definition_snippet(&e, Language::TypeScript),
"export default type Foo"
);
}
#[test]
fn javascript_export_plain() {
let e = mk_export("bar", false, false);
assert_eq!(
export_definition_snippet(&e, Language::JavaScript),
"export bar"
);
}
#[test]
fn python_export_renders_as_bare_name() {
let e = mk_export("Bar", false, false);
assert_eq!(export_definition_snippet(&e, Language::Python), "Bar");
}
}